QC Kak Inno 27 Oct

QC Kak Ayu 27 Oct
QC Keano 27 Oct
QC Pak Jun 27 Oct
This commit is contained in:
2025-10-28 17:34:38 +08:00
parent ed371bd0d9
commit a6663bbcee
27 changed files with 629 additions and 337 deletions

View File

@@ -2,7 +2,7 @@
'use client' 'use client'
import potensiDesaState from '@/app/admin/(dashboard)/_state/desa/potensi'; import potensiDesaState from '@/app/admin/(dashboard)/_state/desa/potensi';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { BackgroundImage, Box, Button, Center, Flex, Group, Paper, SimpleGrid, Skeleton, Stack, Text, Tooltip } from '@mantine/core'; import { BackgroundImage, Box, Button, Center, Flex, Group, Paper, SimpleGrid, Skeleton, Stack, Text } from '@mantine/core';
import { IconEye } from '@tabler/icons-react'; import { IconEye } from '@tabler/icons-react';
import { useTransitionRouter } from 'next-view-transitions'; import { useTransitionRouter } from 'next-view-transitions';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
@@ -114,7 +114,6 @@ function Page() {
</Text> </Text>
</Box> </Box>
<Group justify="center"> <Group justify="center">
<Tooltip label="Lihat detail potensi" withArrow>
<Button <Button
radius="xl" radius="xl"
size="md" size="md"
@@ -126,7 +125,6 @@ function Page() {
> >
Lihat Detail Lihat Detail
</Button> </Button>
</Tooltip>
</Group> </Group>
</Stack> </Stack>
</BackgroundImage> </BackgroundImage>

View File

@@ -95,7 +95,7 @@ function ProfilPerbekel() {
<Box> <Box>
<Stack gap={6}> <Stack gap={6}>
<Stack align="center" gap={6}> <Stack align="center" gap={6}>
<IconUser size={22} color={colors['blue-button']} /> <IconUser size={22} />
<Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Biodata</Text> <Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Biodata</Text>
</Stack> </Stack>
<Text <Text
@@ -111,7 +111,7 @@ function ProfilPerbekel() {
<Box> <Box>
<Stack gap={6}> <Stack gap={6}>
<Stack align="center" gap={6}> <Stack align="center" gap={6}>
<IconBriefcase size={22} color={colors['blue-button']} /> <IconBriefcase size={22} />
<Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Pengalaman</Text> <Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Pengalaman</Text>
</Stack> </Stack>
<Text <Text
@@ -138,7 +138,7 @@ function ProfilPerbekel() {
<Stack gap="xl"> <Stack gap="xl">
<Box> <Box>
<Stack align="center" gap={6} > <Stack align="center" gap={6} >
<IconUsers size={22} color={colors['blue-button']} /> <IconUsers size={22} />
<Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Pengalaman Organisasi</Text> <Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Pengalaman Organisasi</Text>
</Stack> </Stack>
<Text <Text
@@ -152,7 +152,7 @@ function ProfilPerbekel() {
<Box> <Box>
<Stack align="center" gap={6} mb={6}> <Stack align="center" gap={6} mb={6}>
<IconTargetArrow size={22} color={colors['blue-button']} /> <IconTargetArrow size={22} />
<Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Program Kerja Unggulan</Text> <Text fz={{ base: "1.2rem", md: "1.5rem" }} fw="bold">Program Kerja Unggulan</Text>
</Stack> </Stack>
<Box px={10}> <Box px={10}>

View File

@@ -52,7 +52,7 @@ function Page() {
<Box px={{ base: 'md', md: 100 }}> <Box px={{ base: 'md', md: 100 }}>
<BackButton /> <BackButton />
</Box> </Box>
<Box px={{ base: 'md', md: 100 }}> <Box px={{ base: 'md', md: 100 }} pb={80}>
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}> <Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
Lowongan Kerja Lokal Lowongan Kerja Lokal
</Text> </Text>

View File

@@ -55,6 +55,7 @@ function Page() {
}} }}
> >
<Paper p={'xl'} > <Paper p={'xl'} >
<Stack gap={"xs"}>
<Text fz={'h3'} fw={'bold'} c={colors['blue-button']}>Tujuan Ide Inovatif Ini</Text> <Text fz={'h3'} fw={'bold'} c={colors['blue-button']}>Tujuan Ide Inovatif Ini</Text>
<List> <List>
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Mendorong partisipasi aktif masyarakat</ListItem> <ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Mendorong partisipasi aktif masyarakat</ListItem>
@@ -62,6 +63,7 @@ function Page() {
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Memecahkan tantangan komunal</ListItem> <ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Memecahkan tantangan komunal</ListItem>
<ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Mengembangkan potensi kreativitas warga</ListItem> <ListItem ta={'justify'} fz={{ base: 'h4', md: 'lg' }}>Mengembangkan potensi kreativitas warga</ListItem>
</List> </List>
</Stack>
</Paper> </Paper>
<Paper p={'xl'} > <Paper p={'xl'} >
<Flex align={'center'} justify={'space-between'}> <Flex align={'center'} justify={'space-between'}>

View File

@@ -71,11 +71,22 @@ function Page() {
{filteredData.map((v, k) => { {filteredData.map((v, k) => {
return ( return (
<Paper p={'xl'} key={k}> <Paper p={'xl'} key={k}>
<Image src={v.image.link || ''} pb={10} radius={10} alt='' loading="lazy"/> <Stack gap={"xs"}>
<Text fz={'h3'} fw={'bold'} c={colors['blue-button']}>{v.name}</Text> <Image src={v.image.link || ''} pb={10} radius={10} alt='' loading="lazy" />
<Box pr={'lg'} pb={10}> <Text fz={'h3'} fw={'bold'}>{v.name}</Text>
<Text fz={'h4'} fw={'bold'} style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: v.deskripsi }} /> <Box pr={'lg'} pb={10}>
</Box> <Text
size="md"
ta="justify"
lh={1} // line height biar enak dibaca
style={{
wordBreak: "break-word",
whiteSpace: "normal",
}}
dangerouslySetInnerHTML={{ __html: v.deskripsi }}
/>
</Box>
</Stack>
</Paper> </Paper>
) )
})} })}

View File

@@ -75,18 +75,18 @@ function AdministrasiOnline() {
<Title order={3}>Ajukan Administrasi Online</Title> <Title order={3}>Ajukan Administrasi Online</Title>
<TextInput <TextInput
label={<Text fz="sm" fw="bold">Nama</Text>} label={<Text fz="sm" fw="bold">Nama</Text>}
placeholder="masukkan nama" placeholder="Masukkan nama"
onChange={(val) => (state.administrasiOnline.create.form.name = val.target.value)} onChange={(val) => (state.administrasiOnline.create.form.name = val.target.value)}
/> />
<TextInput <TextInput
label={<Text fz="sm" fw="bold">Alamat</Text>} label={<Text fz="sm" fw="bold">Alamat</Text>}
placeholder="masukkan alamat" placeholder="Masukkan alamat"
onChange={(val) => (state.administrasiOnline.create.form.alamat = val.target.value)} onChange={(val) => (state.administrasiOnline.create.form.alamat = val.target.value)}
/> />
<TextInput <TextInput
type="number" type="number"
label={<Text fz="sm" fw="bold">Nomor Telepon</Text>} label={<Text fz="sm" fw="bold">Nomor Telepon</Text>}
placeholder="masukkan nomor telepon" placeholder="Masukkan nomor telepon"
onChange={(val) => (state.administrasiOnline.create.form.nomorTelepon = val.target.value)} onChange={(val) => (state.administrasiOnline.create.form.nomorTelepon = val.target.value)}
/> />
<Select <Select
@@ -95,7 +95,7 @@ function AdministrasiOnline() {
state.administrasiOnline.create.form.jenisLayananId = val ?? ""; state.administrasiOnline.create.form.jenisLayananId = val ?? "";
}} }}
label={<Text fw={"bold"} fz={"sm"}>Jenis Layanan</Text>} label={<Text fw={"bold"} fz={"sm"}>Jenis Layanan</Text>}
placeholder="Pilih kategori produk" placeholder="Pilih jenis layanan"
data={ data={
state.jenisLayanan.findMany.data?.map((v) => ({ state.jenisLayanan.findMany.data?.map((v) => ({
value: v.id, value: v.id,

View File

@@ -0,0 +1,85 @@
/* eslint-disable react-hooks/exhaustive-deps */
'use client'
import stateDashboardBerita from '@/app/admin/(dashboard)/_state/desa/berita';
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
import colors from '@/con/colors';
import { Box, Center, Container, Image, Skeleton, Stack, Text } from '@mantine/core';
import { useParams } from 'next/navigation';
import { useEffect, useState } from 'react';
import { useProxy } from 'valtio/utils';
function Page() {
const params = useParams<{ id: string }>();
const id = Array.isArray(params.id) ? params.id[0] : params.id;
const state = useProxy(stateDashboardBerita.berita)
const [loading, setLoading] = useState(true)
useEffect(() => {
const loadData = async () => {
if (!id) return;
try {
setLoading(true);
await state.findUnique.load(id);
} catch (error) {
console.error('Error loading data:', error);
} finally {
setLoading(false);
}
}
loadData()
}, [id])
if (loading) {
return (
<Center>
<Skeleton height={500} />
</Center>
);
}
if (!state.findUnique.data) {
return (
<Center>
<Text>Data tidak ditemukan</Text>
</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={"2.4rem"} c={colors["blue-button"]} fw={"bold"}>
{state.findUnique.data?.judul}
</Text>
</Box>
<Image src={state.findUnique.data?.image?.link || ''} alt='' w={"100%"} loading="lazy" />
</Container>
<Box px={{ base: "md", md: 100 }}>
<Stack gap={"xs"}>
<Text
py={20}
fz={{ base: "sm", md: "lg" }}
lh={{ base: 1.6, md: 1.8 }} // ✅ line-height lebih rapat dan responsif
ta="justify"
style={{
wordBreak: "break-word",
whiteSpace: "normal",
}}
dangerouslySetInnerHTML={{
__html: state.findUnique.data?.content || "",
}}
/>
</Stack>
</Box>
</Stack>
);
}
export default Page;

View File

@@ -0,0 +1,62 @@
'use client'
import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman';
import BackButton from '@/app/darmasaba/(pages)/desa/layanan/_com/BackButto';
import colors from '@/con/colors';
import { Box, Container, Group, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { useParams } from 'next/navigation';
import { useProxy } from 'valtio/utils';
function Page() {
const detail = useProxy(stateDesaPengumuman.pengumuman.findUnique)
const params = useParams()
useShallowEffect(() => {
stateDesaPengumuman.pengumuman.findUnique.load(params?.id as string)
}, [])
if (!detail.data) {
return (
<Box>
<Skeleton h={400} />
</Box>
)
}
return (
<Stack pos="relative" bg={colors.Bg} py="xl" gap="md">
{/* Header */}
<Box px={{ base: "md", md: 100 }}>
<BackButton />
</Box>
<Container size="lg" px="md">
<Stack gap="xs" >
<Group justify={"space-between"} align={"center"}>
<Text fz={{ base: "2rem", md: "2rem" }} c={colors["blue-button"]} fw="bold" >
{detail.data?.judul}
</Text>
<Group justify='end'>
<Paper bg={colors['blue-button']} p={5}>
<Text c={colors['white-1']}>{detail.data?.CategoryPengumuman?.name}</Text>
</Paper>
</Group>
</Group>
<Paper bg={colors["white-1"]} p="md">
<Text fz={"md"} style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: detail.data?.content }} />
<Text fz={"md"} c={colors["blue-button"]} fw="bold" >
{new Date(detail.data?.createdAt).toLocaleDateString('id-ID', {
weekday: 'long',
day: 'numeric',
month: 'long',
year: 'numeric'
})}
</Text>
</Paper>
</Stack>
</Container>
</Stack>
);
}
export default Page;

View File

@@ -1,20 +1,23 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import stateDashboardBerita from '@/app/admin/(dashboard)/_state/desa/berita'; import stateDashboardBerita from '@/app/admin/(dashboard)/_state/desa/berita';
import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Card, Divider, Grid, GridCol, Image, Paper, Stack, Text, Title } from '@mantine/core'; import { Badge, Box, Card, Divider, Grid, GridCol, Group, Image, Paper, Stack, Text, Title } from '@mantine/core';
import dayjs from 'dayjs'; import dayjs from 'dayjs';
import relativeTime from 'dayjs/plugin/relativeTime'; import relativeTime from 'dayjs/plugin/relativeTime';
import { useEffect } from 'react'; import { useEffect } from 'react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import BackButton from '../../../desa/layanan/_com/BackButto'; import BackButton from '../../../desa/layanan/_com/BackButto';
import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman'; import { useTransitionRouter } from 'next-view-transitions';
import { motion } from "framer-motion";
dayjs.extend(relativeTime); dayjs.extend(relativeTime);
function InformasiDesa() { function InformasiDesa() {
const stateBerita = useProxy(stateDashboardBerita.berita) const router = useTransitionRouter()
const statePengumuman = useProxy(stateDesaPengumuman.pengumuman) const stateBerita = useProxy(stateDashboardBerita.berita);
const statePengumuman = useProxy(stateDesaPengumuman.pengumuman);
useEffect(() => { useEffect(() => {
stateBerita.findFirst.load(); stateBerita.findFirst.load();
@@ -23,116 +26,216 @@ function InformasiDesa() {
statePengumuman.findRecent.load(); statePengumuman.findRecent.load();
}, []); }, []);
const dataBerita = stateBerita.findFirst.data const dataBerita = stateBerita.findFirst.data;
const dataPengumuman = statePengumuman.findFirst.data const dataPengumuman = statePengumuman.findFirst.data;
return ( return (
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}> <Stack pos="relative" bg={colors.Bg} py="xl" gap={22}>
<Box px={{ base: 'md', md: 100 }}> <Box px={{ base: 'md', md: 100 }}>
<BackButton /> <BackButton />
</Box> </Box>
<Box px={{ base: 'md', md: 100 }} >
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}> <Box px={{ base: 'md', md: 100 }}>
<Title ta="center" fz={{ base: 'h1', md: '2.5rem' }} c={colors['blue-button']} fw="bold">
Informasi Desa Informasi Desa
</Text> </Title>
</Box> </Box>
<Box px={{ base: "md", md: 100 }}>
<Stack gap={10}> <Box px={{ base: 'md', md: 100 }}>
<Stack gap={30}>
{/* === BERITA UTAMA === */}
{dataBerita && ( {dataBerita && (
<Paper shadow="md" radius="md" p="md"> <motion.div
<Grid> whileHover={{ scale: 1.05 }}
<GridCol span={{ md: 6, base: 12 }}> whileTap={{ scale: 0.95 }}
<Image style={{ cursor: "pointer" }}
src={dataBerita.image?.link || "/fallback.jpg"} onClick={() => router.push(`/darmasaba/inovasi/layanan-online-desa/informasi-desa/detail-berita/${dataBerita.id}`)}
alt={dataBerita.judul} >
radius="md" <Paper shadow="md" radius="lg" p="lg" withBorder>
fit="cover" <Grid align="center" gutter="xl">
height={250} <GridCol span={{ base: 12, md: 6 }}>
maw={600} <Image
loading="lazy" src={dataBerita.image?.link || '/fallback.jpg'}
/> alt={dataBerita.judul}
</GridCol> radius="md"
<GridCol span={{ md: 6, base: 12 }}> fit="cover"
<Box> height={280}
<Text fz="sm" c="dimmed">{dataBerita.kategoriBerita?.name} {dayjs(dataBerita.createdAt).fromNow()}</Text> loading="lazy"
<Title order={1} fw="bold">{dataBerita.judul}</Title> style={{ objectPosition: 'center' }}
<Text ta={"justify"} mt="xs" fz="md" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: dataBerita.content }} /> />
</Box> </GridCol>
</GridCol> <GridCol span={{ base: 12, md: 6 }}>
</Grid> <Stack gap="xs">
</Paper> <Title order={2} fw={800}>
{dataBerita.judul}
</Title>
<Group justify='space-between'>
<Badge bg={colors['blue-button']}>
{dataBerita.kategoriBerita?.name}
</Badge>
<Text fz="sm" c="dimmed">
{dayjs(dataBerita.createdAt).fromNow()}
</Text>
</Group>
<Text
ta="justify"
mt="xs"
fz="md"
lh={1.7}
lineClamp={6}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
dangerouslySetInnerHTML={{ __html: dataBerita.content }}
/>
</Stack>
</GridCol>
</Grid>
</Paper>
</motion.div>
)} )}
<Stack py={10}>
<Title order={3}>Berita Terbaru</Title> {/* === BERITA TERBARU === */}
<Grid> <Stack>
<Title order={3} fw={700}>
Berita Terbaru
</Title>
<Grid gutter="xl">
{stateBerita.findRecent.data.map((item) => ( {stateBerita.findRecent.data.map((item) => (
<GridCol span={{ base: 12, sm: 6, md: 3 }} key={item.id}> <GridCol span={{ base: 12, sm: 6, md: 3 }} key={item.id}>
<Card shadow="sm" radius="md" withBorder h="100%"> <motion.div
<Card.Section> whileHover={{ scale: 1.05 }}
<Image whileTap={{ scale: 0.95 }}
src={item.image?.link || "/placeholder.jpg"} style={{ cursor: "pointer" }}
alt={item.judul} onClick={() => router.push(`/darmasaba/inovasi/layanan-online-desa/informasi-desa/detail-berita/${item.id}`)}
height={160} // gambar fix height >
fit="cover" <Card
loading="lazy" shadow="sm"
/> radius="md"
</Card.Section> withBorder
<Stack gap="xs" mt="sm"> h="100%"
<Text fw={600} lineClamp={2}> >
{item.judul} <Card.Section>
</Text> <Image
<Text size="sm" color="dimmed" lineClamp={2}> src={item.image?.link || '/placeholder.jpg'}
{item.deskripsi} alt={item.judul}
</Text> height={160}
<Text size="xs" c="gray"> fit="cover"
{dayjs(item.createdAt).fromNow()} radius="sm"
</Text> loading="lazy"
</Stack> />
</Card> </Card.Section>
<Stack gap={4} mt="sm">
<Text ta="justify"
size="sm"
c="dimmed"
lineClamp={3}
style={{
wordBreak: "break-word",
overflow: "hidden",
textOverflow: "ellipsis",
whiteSpace: "normal",
lineHeight: 1.5,
display: "-webkit-box",
WebkitLineClamp: 3,
WebkitBoxOrient: "vertical",
}}
dangerouslySetInnerHTML={{ __html: item.deskripsi || '-' }} />
<Text size="xs" c="gray">
{dayjs(item.createdAt).fromNow()}
</Text>
</Stack>
</Card>
</motion.div>
</GridCol> </GridCol>
))} ))}
</Grid> </Grid>
</Stack> </Stack>
<Divider color={colors['blue-button']} my="md" />
<Grid> <Divider color={colors['blue-button']} my="lg" />
<GridCol span={{ md: 6, base: 12 }}>
{/* === PENGUMUMAN === */}
<Grid gutter="xl" align="stretch">
<GridCol span={{ base: 12, md: 6 }}>
{dataPengumuman && ( {dataPengumuman && (
<Paper h={"97%"} shadow="md" radius="md" p="md"> <motion.div
<Stack gap={"xs"}> onClick={() => router.push(`/darmasaba/inovasi/layanan-online-desa/informasi-desa/detail-pengumuman/${dataPengumuman.id}`)}
<Title order={1} fw="bold">{dataPengumuman.judul}</Title> whileHover={{ scale: 1.05 }}
<Text fz="sm" c="dimmed">{dataPengumuman.CategoryPengumuman?.name} {dayjs(dataPengumuman.createdAt).fromNow()}</Text> whileTap={{ scale: 0.95 }}
<Box> style={{ cursor: "pointer" }}
<Text ta={"justify"} mt="xs" fz="md" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: dataPengumuman.content }} /> >
</Box> <Paper shadow="md" radius="lg" p="lg" h="100%" withBorder>
</Stack> <Stack gap="xs">
</Paper> <Title order={2} fw={800}>
{dataPengumuman.judul}
</Title>
<Group justify='space-between'>
<Badge bg={colors['blue-button']}>
{dataPengumuman.CategoryPengumuman?.name}
</Badge>
<Text fz="sm" c="dimmed">
{dayjs(dataPengumuman.createdAt).fromNow()}
</Text>
</Group>
<Text
ta="justify"
mt="xs"
fz="md"
lh={1.7}
lineClamp={8}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
dangerouslySetInnerHTML={{ __html: dataPengumuman.content }}
/>
</Stack>
</Paper>
</motion.div>
)} )}
</GridCol> </GridCol>
<GridCol span={{ md: 6, base: 12 }}>
<Stack py={10}> <GridCol span={{ base: 12, md: 6 }}>
<Title order={3}>Pengumuman Terbaru</Title> <Stack>
<Grid> <Title order={3} fw={700}>
Pengumuman Terbaru
</Title>
<Grid gutter="lg">
{statePengumuman.findRecent.data.map((item) => ( {statePengumuman.findRecent.data.map((item) => (
<GridCol span={{ base: 12, sm: 8, md: 6 }} key={item.id}> <GridCol span={{ base: 12, sm: 6 }} key={item.id}>
<Card shadow="sm" radius="md" withBorder h="100%"> <motion.div
<Stack gap="xs" mt="sm"> whileHover={{ scale: 1.05 }}
<Text fw={600} lineClamp={2}> whileTap={{ scale: 0.95 }}
{item.judul} style={{ cursor: "pointer" }}
</Text> onClick={() => router.push(`/darmasaba/inovasi/layanan-online-desa/informasi-desa/detail-pengumuman/${item.id}`)}
<Text size="sm" color="dimmed" lineClamp={2}> >
{item.deskripsi} <Card
</Text> shadow="xs"
<Text size="xs" c="gray"> radius="md"
{dayjs(item.createdAt).fromNow()} withBorder
</Text> h="100%"
</Stack> p="md"
</Card> style={{ transition: '0.2s ease' }}
className="hover:shadow-md"
>
<Stack gap="xs">
<Text fw={600} lineClamp={2}>
{item.judul}
</Text>
<Text
ta="justify"
mt="xs"
fz="md"
lh={1.7}
lineClamp={2}
style={{ wordBreak: 'break-word', whiteSpace: 'normal' }}
dangerouslySetInnerHTML={{ __html: item.content }}
/>
<Text size="xs" c="gray">
{dayjs(item.createdAt).fromNow()}
</Text>
</Stack>
</Card>
</motion.div>
</GridCol> </GridCol>
))} ))}
</Grid> </Grid>
</Stack> </Stack>
</GridCol> </GridCol>
</Grid> </Grid>

View File

@@ -100,33 +100,33 @@ function PengaduanMasyarakat() {
<Title order={3}>Ajukan Pengaduan Masyarakat</Title> <Title order={3}>Ajukan Pengaduan Masyarakat</Title>
<TextInput <TextInput
label={<Text fz="sm" fw="bold">Nama</Text>} label={<Text fz="sm" fw="bold">Nama</Text>}
placeholder="masukkan nama" placeholder="Masukkan nama"
onChange={(val) => (state.pengaduanMasyarakat.create.form.name = val.target.value)} onChange={(val) => (state.pengaduanMasyarakat.create.form.name = val.target.value)}
/> />
<TextInput <TextInput
label={<Text fz="sm" fw="bold">Email</Text>} label={<Text fz="sm" fw="bold">Email</Text>}
placeholder="masukkan email" placeholder="Masukkan email"
onChange={(val) => (state.pengaduanMasyarakat.create.form.email = val.target.value)} onChange={(val) => (state.pengaduanMasyarakat.create.form.email = val.target.value)}
/> />
<TextInput <TextInput
type="number" type="number"
label={<Text fz="sm" fw="bold">Nomor Telepon</Text>} label={<Text fz="sm" fw="bold">Nomor Telepon</Text>}
placeholder="masukkan nomor telepon" placeholder="Masukkan nomor telepon"
onChange={(val) => (state.pengaduanMasyarakat.create.form.nomorTelepon = val.target.value)} onChange={(val) => (state.pengaduanMasyarakat.create.form.nomorTelepon = val.target.value)}
/> />
<TextInput <TextInput
label={<Text fz="sm" fw="bold">NIK</Text>} label={<Text fz="sm" fw="bold">NIK</Text>}
placeholder="masukkan nik" placeholder="Masukkan nik"
onChange={(val) => (state.pengaduanMasyarakat.create.form.nik = val.target.value)} onChange={(val) => (state.pengaduanMasyarakat.create.form.nik = val.target.value)}
/> />
<TextInput <TextInput
label={<Text fz="sm" fw="bold">Judul Pengaduan</Text>} label={<Text fz="sm" fw="bold">Judul Pengaduan</Text>}
placeholder="masukkan judul pengaduan" placeholder="Masukkan judul pengaduan"
onChange={(val) => (state.pengaduanMasyarakat.create.form.judulPengaduan = val.target.value)} onChange={(val) => (state.pengaduanMasyarakat.create.form.judulPengaduan = val.target.value)}
/> />
<TextInput <TextInput
label={<Text fz="sm" fw="bold">Lokasi Kejadian</Text>} label={<Text fz="sm" fw="bold">Lokasi Kejadian</Text>}
placeholder="masukkan lokasi kejadian" placeholder="Masukkan lokasi kejadian"
onChange={(val) => (state.pengaduanMasyarakat.create.form.lokasiKejadian = val.target.value)} onChange={(val) => (state.pengaduanMasyarakat.create.form.lokasiKejadian = val.target.value)}
/> />
<Box> <Box>
@@ -144,7 +144,7 @@ function PengaduanMasyarakat() {
state.pengaduanMasyarakat.create.form.jenisPengaduanId = val ?? ""; state.pengaduanMasyarakat.create.form.jenisPengaduanId = val ?? "";
}} }}
label={<Text fw={"bold"} fz={"sm"}>Jenis Pengaduan</Text>} label={<Text fw={"bold"} fz={"sm"}>Jenis Pengaduan</Text>}
placeholder="Pilih kategori produk" placeholder="Pilih jenis pengaduan"
data={ data={
state.jenisPengaduan.findMany.data?.map((v) => ({ state.jenisPengaduan.findMany.data?.map((v) => ({
value: v.id, value: v.id,

View File

@@ -54,14 +54,14 @@ function ArtikelKesehatanPage() {
<Image style={{ borderTopLeftRadius: '10px', borderTopRightRadius: '10px' }} src={item.image?.link} alt={item.title} height={200} fit="cover" loading="lazy" /> <Image style={{ borderTopLeftRadius: '10px', borderTopRightRadius: '10px' }} src={item.image?.link} alt={item.title} height={200} fit="cover" loading="lazy" />
</Card.Section> </Card.Section>
<Stack gap="xs" mt="md"> <Stack gap="xs" mt="md">
<Text fw="bold" fz="xl" c="dark">{item.title}</Text> <Text fw="bold" fz="xl" c={colors['blue-button']}>{item.title}</Text>
<Group gap="xs"> <Group gap="xs">
<IconCalendar size={16} color={colors['blue-button']} /> <IconCalendar size={16} color='gray' />
<Text fz="sm" c="dimmed"> <Text fz="sm" c="dimmed">
{new Date(item.createdAt).toLocaleDateString('id-ID', { year: 'numeric', month: 'long', day: 'numeric' })} Dinas Kesehatan {new Date(item.createdAt).toLocaleDateString('id-ID', { year: 'numeric', month: 'long', day: 'numeric' })} Dinas Kesehatan
</Text> </Text>
</Group> </Group>
<Text fz="md" c="dark" lineClamp={3}> <Text fz="md" lineClamp={3}>
{item.content} {item.content}
</Text> </Text>
<Group justify="flex-start"> <Group justify="flex-start">

View File

@@ -73,14 +73,14 @@ function FasilitasKesehatanPage() {
</Badge> </Badge>
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<IconMapPin size={18} stroke={1.5} color={colors['blue-button']} /> <IconMapPin size={18} stroke={1.5} />
<Text fz="sm" c="dimmed"> <Text fz="sm">
{item.informasiumum.alamat} {item.informasiumum.alamat}
</Text> </Text>
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<IconClock size={18} stroke={1.5} color={colors['blue-button']} /> <IconClock size={18} stroke={1.5} />
<Text fz="sm" c="dimmed"> <Text fz="sm">
{item.informasiumum.jamOperasional} {item.informasiumum.jamOperasional}
</Text> </Text>
</Group> </Group>

View File

@@ -49,7 +49,7 @@ function JadwalKegiatanPage() {
> >
<Stack gap="sm"> <Stack gap="sm">
<Group justify="space-between"> <Group justify="space-between">
<Text fw={700} fz="xl"> <Text fw={700} fz="xl" c={colors['blue-button']}>
{item.informasijadwalkegiatan.name} {item.informasijadwalkegiatan.name}
</Text> </Text>
<Text fw={600} fz="sm" c={colors['blue-button']}> <Text fw={600} fz="sm" c={colors['blue-button']}>
@@ -62,12 +62,12 @@ function JadwalKegiatanPage() {
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<IconClockHour4 size={18} color={colors['blue-button']} /> <IconClockHour4 size={18} />
<Text fz="sm">{item.informasijadwalkegiatan.waktu}</Text> <Text fz="sm">{item.informasijadwalkegiatan.waktu}</Text>
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<IconMapPin size={18} color={colors['blue-button']} /> <IconMapPin size={18} />
<Text fz="sm">{item.informasijadwalkegiatan.lokasi}</Text> <Text fz="sm">{item.informasijadwalkegiatan.lokasi}</Text>
</Group> </Group>

View File

@@ -73,7 +73,6 @@ function DetailInfoWabahPenyakitUser() {
<Text fz="lg" fw="bold">Deskripsi</Text> <Text fz="lg" fw="bold">Deskripsi</Text>
<Text <Text
fz="md" fz="md"
c="dimmed"
dangerouslySetInnerHTML={{ __html: data.deskripsiLengkap || '-' }} dangerouslySetInnerHTML={{ __html: data.deskripsiLengkap || '-' }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }} style={{ wordBreak: "break-word", whiteSpace: "normal" }}
/> />

View File

@@ -53,7 +53,7 @@ function Page() {
<Text fz={{ base: '2rem', md: '2.8rem' }} c={colors['blue-button']} fw={800}> <Text fz={{ base: '2rem', md: '2.8rem' }} c={colors['blue-button']} fw={800}>
Kontak Darurat Kontak Darurat
</Text> </Text>
<Text c="dimmed" fz="md" mt={4}> <Text fz="md" mt={4}>
Hubungi layanan penting dengan cepat dan mudah Hubungi layanan penting dengan cepat dan mudah
</Text> </Text>
</GridCol> </GridCol>
@@ -128,7 +128,7 @@ function Page() {
<Text ta="center" fw={700} fz="lg" c={colors['blue-button']}> <Text ta="center" fw={700} fz="lg" c={colors['blue-button']}>
{v.name} {v.name}
</Text> </Text>
<Text fz="sm" c="dimmed" ta="center" lineClamp={3}> <Text fz="sm" ta="center" lineClamp={3}>
<span style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: v.deskripsi }} /> <span style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: v.deskripsi }} />
</Text> </Text>
<Button <Button

View File

@@ -52,7 +52,7 @@ function Page() {
<Text fz={{ base: 30, md: 40 }} c={colors['blue-button']} fw={800} lh={1.2}> <Text fz={{ base: 30, md: 40 }} c={colors['blue-button']} fw={800} lh={1.2}>
Penanganan Darurat Penanganan Darurat
</Text> </Text>
<Text fz="md" c="dimmed" mt={4}> <Text fz="md" mt={4}>
Informasi cepat dan jelas untuk situasi darurat kesehatan Informasi cepat dan jelas untuk situasi darurat kesehatan
</Text> </Text>
</GridCol> </GridCol>
@@ -105,36 +105,28 @@ function Page() {
onMouseLeave={(e) => (e.currentTarget.style.transform = 'translateY(0)')} onMouseLeave={(e) => (e.currentTarget.style.transform = 'translateY(0)')}
> >
<Stack align="center" gap="md"> <Stack align="center" gap="md">
<Center> <Box
<Box style={{
width: '100%',
aspectRatio: '16/9',
borderRadius: '12px',
overflow: 'hidden',
position: 'relative',
}}
>
<Image
src={v.image.link}
alt={v.name}
fit="cover"
loading="lazy"
style={{ style={{
width: '100%', width: '100%',
height: 180, // 🔥 tinggi fix biar semua seragam height: '100%',
borderRadius: 12, transition: 'transform 0.4s ease',
overflow: 'hidden',
position: 'relative',
backgroundColor: '#f0f2f5', // fallback kalau gambar loading
}} }}
> />
<Image </Box>
src={v.image?.link || '/img/default.png'}
alt={v.name}
fit="cover"
width="100%"
height="100%"
loading="lazy"
style={{
objectFit: 'cover',
objectPosition: 'center',
transition: 'transform 0.4s ease',
}}
onMouseEnter={(e) => (e.currentTarget.style.transform = 'scale(1.05)')}
onMouseLeave={(e) => (e.currentTarget.style.transform = 'scale(1)')}
/>
</Box>
</Center>
<Stack gap={4} w="100%"> <Stack gap={4} w="100%">
<Text <Text
fz="lg" fz="lg"
@@ -147,8 +139,7 @@ function Page() {
</Text> </Text>
<Box> <Box>
<Text <Text
fz="sm" fz="md"
c="dimmed"
lineClamp={3} lineClamp={3}
dangerouslySetInnerHTML={{ __html: v.deskripsi }} dangerouslySetInnerHTML={{ __html: v.deskripsi }}
style={{ wordBreak: "break-word", whiteSpace: "normal" }} style={{ wordBreak: "break-word", whiteSpace: "normal" }}
@@ -159,6 +150,8 @@ function Page() {
size="md" size="md"
component="a" component="a"
href={`/darmasaba/kesehatan/penanganan-darurat/${v.id}`} href={`/darmasaba/kesehatan/penanganan-darurat/${v.id}`}
bg={colors['blue-button']}
c="white"
> >
Lihat Detail Lihat Detail
</Button> </Button>

View File

@@ -28,10 +28,11 @@ function Page() {
} }
return ( return (
<Stack pos="relative" bg={colors.Bg} py="xl" gap="xl"> <Stack bg={colors.Bg} py="xl" gap="xl">
<Box px={{ base: 'md', md: 100 }}> <Box px={{ base: 'md', md: 100 }}>
<BackButton /> <BackButton />
</Box> </Box>
<Box px={{ base: 'md', md: 100 }}>
<Paper <Paper
px={{ base: 'md', md: 100 }} px={{ base: 'md', md: 100 }}
py="xl" py="xl"
@@ -70,7 +71,7 @@ function Page() {
<Group gap="xl"> <Group gap="xl">
<Group gap="xs"> <Group gap="xs">
<Tooltip label="Tanggal dibuat" withArrow> <Tooltip label="Tanggal dibuat" withArrow>
<IconCalendar size={20} stroke={1.5} /> <IconCalendar color='gray' size={20} stroke={1.5} />
</Tooltip> </Tooltip>
<Text size="sm" c="dimmed"> <Text size="sm" c="dimmed">
{state.findUnique.data.createdAt {state.findUnique.data.createdAt
@@ -84,13 +85,14 @@ function Page() {
</Group> </Group>
<Group gap="xs"> <Group gap="xs">
<Tooltip label="Dibuat oleh" withArrow> <Tooltip label="Dibuat oleh" withArrow>
<IconUser size={20} stroke={1.5} /> <IconUser color='gray' size={20} stroke={1.5} />
</Tooltip> </Tooltip>
<Text size="sm" c="dimmed">Admin Desa</Text> <Text size="sm" c="dimmed">Admin Desa</Text>
</Group> </Group>
</Group> </Group>
</Stack> </Stack>
</Paper> </Paper>
</Box>
</Stack> </Stack>
); );
} }

View File

@@ -1,4 +1,5 @@
'use client' 'use client'
import programKesehatan from "@/app/admin/(dashboard)/_state/kesehatan/program-kesehatan/programKesehatan";
import colors from "@/con/colors"; import colors from "@/con/colors";
import { import {
Box, Box,
@@ -15,9 +16,9 @@ import {
Stack, Stack,
Text, Text,
TextInput, TextInput,
Tooltip, Transition
Transition,
} from "@mantine/core"; } from "@mantine/core";
import { useDebouncedValue, useShallowEffect } from "@mantine/hooks";
import { import {
IconBarbell, IconBarbell,
IconCalendar, IconCalendar,
@@ -26,12 +27,10 @@ import {
IconUser, IconUser,
IconUsersGroup, IconUsersGroup,
} from "@tabler/icons-react"; } 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";
import { useState } from "react";
import { useDebouncedValue, useShallowEffect } from "@mantine/hooks";
import { useRouter } from "next/navigation"; import { useRouter } from "next/navigation";
import { useState } from "react";
import { useProxy } from "valtio/utils";
import BackButton from "../../desa/layanan/_com/BackButto";
const manfaatProgram = [ const manfaatProgram = [
{ {
@@ -194,7 +193,6 @@ export default function Page() {
<Text size="sm">Admin Desa</Text> <Text size="sm">Admin Desa</Text>
</Group> </Group>
</Group> </Group>
<Tooltip label="Lihat detail program" withArrow>
<Button <Button
mt="lg" mt="lg"
fullWidth fullWidth
@@ -211,7 +209,6 @@ export default function Page() {
> >
Lihat Detail Lihat Detail
</Button> </Button>
</Tooltip>
</Box> </Box>
</Stack> </Stack>
</Paper> </Paper>

View File

@@ -93,20 +93,23 @@ function Page() {
<Text fw={600} fz="lg" lineClamp={1}>{v.name}</Text> <Text fw={600} fz="lg" lineClamp={1}>{v.name}</Text>
<Badge color="blue" variant="light" radius="sm" fz="xs">Aktif</Badge> <Badge color="blue" variant="light" radius="sm" fz="xs">Aktif</Badge>
</Group> </Group>
<Stack gap={4}> <Stack gap={6}>
<Group gap="xs"> <Group gap="xs" align="flex-start" wrap="nowrap">
<IconMapPin size={16} /> <Box pt={2}><IconMapPin size={16} /></Box>
<Text fz="sm" c="dimmed" lineClamp={2}>{v.alamat}</Text> <Text fz="sm" c="dimmed">{v.alamat}</Text>
</Group> </Group>
<Group gap="xs">
<IconPhone size={16} /> <Group gap="xs" align="flex-start" wrap="nowrap">
<Box pt={2}><IconPhone size={16} /></Box>
<Text fz="sm" c="dimmed">{v.kontak.kontakPuskesmas}</Text> <Text fz="sm" c="dimmed">{v.kontak.kontakPuskesmas}</Text>
</Group> </Group>
<Group gap="xs">
<IconMail size={16} /> <Group gap="xs" align="flex-start" wrap="nowrap">
<Box pt={2}><IconMail size={16} /></Box>
<Text fz="sm" c="dimmed">{v.kontak.email}</Text> <Text fz="sm" c="dimmed">{v.kontak.email}</Text>
</Group> </Group>
</Stack> </Stack>
<Anchor <Anchor
href={`/darmasaba/kesehatan/puskesmas/${v.id}`} href={`/darmasaba/kesehatan/puskesmas/${v.id}`}
fz="sm" fz="sm"

View File

@@ -45,9 +45,8 @@ export function EdukasiCard({ icon, title, description, color = '#1e88e5' }: Edu
alignItems: 'center', alignItems: 'center',
justifyContent: 'center' justifyContent: 'center'
}} }}
> dangerouslySetInnerHTML={{ __html: title }}
{title} />
</Text>
</Tooltip> </Tooltip>
</Stack> </Stack>
<Text <Text

View File

@@ -1,13 +1,13 @@
'use client' 'use client'
import beasiswaDesaState from '@/app/admin/(dashboard)/_state/pendidikan/beasiswa-desa'; import beasiswaDesaState from '@/app/admin/(dashboard)/_state/pendidikan/beasiswa-desa';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Button, Center, Group, Image, Modal, Pagination, Paper, Select, SimpleGrid, Skeleton, Stack, Stepper, StepperStep, Text, TextInput, Title } from '@mantine/core'; import { Box, Button, Center, Group, Image, Modal, Pagination, Paper, Select, SimpleGrid, Skeleton, Stack, Stepper, Text, TextInput, Title } from '@mantine/core';
import { useDisclosure, useShallowEffect } from '@mantine/hooks'; import { useDisclosure, useShallowEffect } from '@mantine/hooks';
import { IconArrowRight, IconCoin, IconInfoCircle, IconSchool, IconUsers } from '@tabler/icons-react'; import { IconArrowRight, IconCoin, IconInfoCircle, IconSchool, IconUsers } from '@tabler/icons-react';
import { useTransitionRouter } from 'next-view-transitions';
import { useState } from 'react'; import { useState } from 'react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto'; import BackButton from '../../desa/layanan/_com/BackButto';
import { useTransitionRouter } from 'next-view-transitions';
const dataBeasiswa = [ const dataBeasiswa = [
{ id: 1, nama: 'Penerima Beasiswa', jumlah: '250+', icon: IconUsers }, { id: 1, nama: 'Penerima Beasiswa', jumlah: '250+', icon: IconUsers },
@@ -27,7 +27,7 @@ function Page() {
tempatLahir: "", tempatLahir: "",
tanggalLahir: "", tanggalLahir: "",
jenisKelamin: "", jenisKelamin: "",
kewarganegaraan: "", kewarganegaraan: "WNI",
agama: "", agama: "",
alamatKTP: "", alamatKTP: "",
alamatDomisili: "", alamatDomisili: "",
@@ -50,9 +50,21 @@ function Page() {
close(); close();
}; };
const timeline = [
{ label: "1 Maret 2025", desc: "Pembukaan Pendaftaran", date: new Date("2025-03-01") },
{ label: "15 Maret 2025", desc: "Seleksi Administrasi", date: new Date("2025-03-15") },
{ label: "1 April 2025", desc: "Tes Potensi Akademik", date: new Date("2025-04-01") },
{ label: "15 April 2025", desc: "Wawancara", date: new Date("2025-04-15") },
{ label: "1 Mei 2025", desc: "Pengumuman Hasil", date: new Date("2025-05-01") },
];
const [active, setActive] = useState(1); const [active, setActive] = useState(1);
const nextStep = () => setActive((current) => (current < 5 ? current + 1 : current)); useShallowEffect(() => {
const prevStep = () => setActive((current) => (current > 0 ? current - 1 : current)); const today = new Date();
// cari berapa banyak tanggal yang sudah lewat
const doneSteps = timeline.filter(item => today >= item.date).length;
setActive(doneSteps); // active step diset sesuai tanggal
}, []);
if (loading || !data) { if (loading || !data) {
return ( return (
@@ -115,7 +127,7 @@ function Page() {
{data.map((v, k) => ( {data.map((v, k) => (
<Paper key={k} p="xl" radius="xl" shadow="sm" bg={colors['white-trans-1']}> <Paper key={k} p="xl" radius="xl" shadow="sm" bg={colors['white-trans-1']}>
<Title order={3} fw={700} c={colors['blue-button']} mb="xs">{v.judul}</Title> <Title order={3} fw={700} c={colors['blue-button']} mb="xs">{v.judul}</Title>
<Text fz="sm" c="dimmed" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: v.deskripsi }}/> <Text fz="sm" c="dimmed" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: v.deskripsi }} />
</Paper> </Paper>
))} ))}
</SimpleGrid> </SimpleGrid>
@@ -139,19 +151,22 @@ function Page() {
Timeline Pendaftaran Timeline Pendaftaran
</Title> </Title>
<Center> <Center>
<Stepper mt={20} active={active} onStepClick={setActive} orientation="vertical" allowNextStepsSelect={false}> <Stepper
<StepperStep label="1 Maret 2025" description="Pembukaan Pendaftaran" /> mt={20}
<StepperStep label="15 Maret 2025" description="Seleksi Administrasi" /> active={active}
<StepperStep label="1 April 2025" description="Tes Potensi Akademik" /> onStepClick={setActive}
<StepperStep label="15 April 2025" description="Wawancara" /> orientation="vertical"
<StepperStep label="1 Mei 2025" description="Pengumuman Hasil" /> allowNextStepsSelect={false}
>
{timeline.map((item, index) => (
<Stepper.Step
key={index}
label={item.label}
description={item.desc}
/>
))}
</Stepper> </Stepper>
</Center> </Center>
<Group justify="center" mt="xl">
<Button variant="default" radius="xl" onClick={prevStep}>Kembali</Button>
<Button radius="xl" bg={colors['blue-button']} onClick={nextStep}>Lanjut</Button>
</Group>
</Box> </Box>
<Modal <Modal
@@ -194,7 +209,11 @@ function Page() {
<TextInput <TextInput
label="Kewarganegaraan" label="Kewarganegaraan"
placeholder="Masukkan kewarganegaraan" placeholder="Masukkan kewarganegaraan"
onChange={(val) => { beasiswaDesa.create.form.kewarganegaraan = val.target.value }} /> value={beasiswaDesa.create.form.kewarganegaraan || "WNI"} // tampilkan WNI kalau kosong
onChange={(e) => {
beasiswaDesa.create.form.kewarganegaraan = e.target.value;
}}
/>
<Select <Select
label="Agama" label="Agama"
placeholder="Pilih agama" placeholder="Pilih agama"

View File

@@ -34,7 +34,7 @@ export default function BeasiswaPage() {
tempatLahir: "", tempatLahir: "",
tanggalLahir: "", tanggalLahir: "",
jenisKelamin: "", jenisKelamin: "",
kewarganegaraan: "", kewarganegaraan: "WNI",
agama: "", agama: "",
alamatKTP: "", alamatKTP: "",
alamatDomisili: "", alamatDomisili: "",
@@ -71,7 +71,7 @@ export default function BeasiswaPage() {
<Stack gap="md" maw={600}> <Stack gap="md" maw={600}>
<Group> <Group>
<IconSchool size={30} color={colors["blue-button"]} /> <IconSchool size={30} color={colors["blue-button"]} />
<Title order={2}>Program Beasiswa Pendidikan Desa Darmasaba</Title> <Title order={2} c={colors["blue-button"]}>Program Beasiswa Pendidikan Desa Darmasaba</Title>
</Group> </Group>
<Text> <Text>
Program ini bertujuan untuk mendukung pendidikan generasi muda di Desa Darmasaba Program ini bertujuan untuk mendukung pendidikan generasi muda di Desa Darmasaba
@@ -84,7 +84,7 @@ export default function BeasiswaPage() {
<Container size="lg" py="xl"> <Container size="lg" py="xl">
<Group mb="sm"> <Group mb="sm">
<IconInfoCircle size={24} color={colors["blue-button"]} /> <IconInfoCircle size={24} color={colors["blue-button"]} />
<Title order={3}>Tentang Program</Title> <Title order={3} c={colors["blue-button"]}>Tentang Program</Title>
</Group> </Group>
<Text> <Text>
Program Beasiswa Desa Darmasaba adalah inisiatif pemerintah desa untuk meningkatkan akses Program Beasiswa Desa Darmasaba adalah inisiatif pemerintah desa untuk meningkatkan akses
@@ -94,12 +94,11 @@ export default function BeasiswaPage() {
{/* Tambahkan info tahun berjalan di sini */} {/* Tambahkan info tahun berjalan di sini */}
<Paper mt="md" p="md" radius="lg" shadow="xs" bg="#f8fbff" withBorder> <Paper mt="md" p="md" radius="lg" shadow="xs" bg="#f8fbff" withBorder>
<Text fw={500} c={colors["blue-button"]}> <Text fw={500}>
📅 Periode Beasiswa Tahun 2025 Periode Beasiswa Tahun 2025
</Text> </Text>
<Text fz="sm" c="dimmed"> <Text fz="sm" c="dimmed">
Pendaftaran beasiswa dibuka mulai <strong>1 Januari 2025</strong> dan ditutup pada Pendaftaran beasiswa dibuka mulai <strong>1 Januari 2025</strong> dan ditutup pada <strong>31 Mei 2025</strong>.
<strong>31 Mei 2025</strong>.
Pengumuman hasil seleksi akan diumumkan pada pertengahan Juni 2025 melalui website resmi Desa Darmasaba. Pengumuman hasil seleksi akan diumumkan pada pertengahan Juni 2025 melalui website resmi Desa Darmasaba.
</Text> </Text>
</Paper> </Paper>
@@ -109,7 +108,7 @@ export default function BeasiswaPage() {
<Container size="lg" py="xl"> <Container size="lg" py="xl">
<Group mb="sm"> <Group mb="sm">
<IconChecklist size={24} color={colors["blue-button"]} /> <IconChecklist size={24} color={colors["blue-button"]} />
<Title order={3}>Syarat Pendaftaran</Title> <Title order={3} c={colors["blue-button"]}>Syarat Pendaftaran</Title>
</Group> </Group>
<SimpleGrid cols={{ base: 1, sm: 2, md: 3 }} spacing="lg"> <SimpleGrid cols={{ base: 1, sm: 2, md: 3 }} spacing="lg">
@@ -140,7 +139,7 @@ export default function BeasiswaPage() {
<Container size="lg" py="xl"> <Container size="lg" py="xl">
<Group mb="sm"> <Group mb="sm">
<IconTimeline size={24} color={colors["blue-button"]} /> <IconTimeline size={24} color={colors["blue-button"]} />
<Title order={3}>Proses Seleksi</Title> <Title order={3} c={colors["blue-button"]}>Proses Seleksi</Title>
</Group> </Group>
<Timeline active={4} bulletSize={24} lineWidth={2}> <Timeline active={4} bulletSize={24} lineWidth={2}>
@@ -148,8 +147,8 @@ export default function BeasiswaPage() {
<Text c="dimmed" size="sm"> <Text c="dimmed" size="sm">
Calon peserta mengisi formulir pendaftaran dan mengunggah dokumen pendukung. Calon peserta mengisi formulir pendaftaran dan mengunggah dokumen pendukung.
</Text> </Text>
<Text size="sm" fw={500} c={colors["blue-button"]} mt={4}> <Text size="sm" fw={500} mt={4}>
Estimasi waktu: 1 Februari 31 Mei 2025 Estimasi waktu: 1 Februari 31 Mei 2025
</Text> </Text>
</Timeline.Item> </Timeline.Item>
@@ -157,8 +156,8 @@ export default function BeasiswaPage() {
<Text c="dimmed" size="sm"> <Text c="dimmed" size="sm">
Panitia memverifikasi kelengkapan dan validitas berkas. Panitia memverifikasi kelengkapan dan validitas berkas.
</Text> </Text>
<Text size="sm" fw={500} c={colors["blue-button"]} mt={4}> <Text size="sm" fw={500} mt={4}>
Estimasi waktu: 57 hari kerja setelah penutupan pendaftaran Estimasi waktu: 57 hari kerja setelah penutupan pendaftaran
</Text> </Text>
</Timeline.Item> </Timeline.Item>
@@ -166,8 +165,8 @@ export default function BeasiswaPage() {
<Text c="dimmed" size="sm"> <Text c="dimmed" size="sm">
Peserta yang lolos administrasi akan diundang untuk wawancara langsung dengan tim seleksi. Peserta yang lolos administrasi akan diundang untuk wawancara langsung dengan tim seleksi.
</Text> </Text>
<Text size="sm" fw={500} c={colors["blue-button"]} mt={4}> <Text size="sm" fw={500} mt={4}>
Estimasi waktu: 710 hari kerja setelah pengumuman seleksi administrasi Estimasi waktu: 710 hari kerja setelah pengumuman seleksi administrasi
</Text> </Text>
</Timeline.Item> </Timeline.Item>
@@ -175,14 +174,14 @@ export default function BeasiswaPage() {
<Text c="dimmed" size="sm"> <Text c="dimmed" size="sm">
Daftar penerima beasiswa diumumkan melalui website resmi Desa Darmasaba. Daftar penerima beasiswa diumumkan melalui website resmi Desa Darmasaba.
</Text> </Text>
<Text size="sm" fw={500} c={colors["blue-button"]} mt={4}> <Text size="sm" fw={500} mt={4}>
Estimasi waktu: 5 hari kerja setelah tahap wawancara selesai Estimasi waktu: 5 hari kerja setelah tahap wawancara selesai
</Text> </Text>
</Timeline.Item> </Timeline.Item>
</Timeline> </Timeline>
<Text c="dimmed" size="sm" mt="lg" ta="center"> <Text c="dimmed" size="sm" mt="lg" ta="center">
🗓 Total estimasi keseluruhan proses: sekitar 34 minggu setelah penutupan pendaftaran Total estimasi keseluruhan proses: sekitar 34 minggu setelah penutupan pendaftaran
</Text> </Text>
</Container> </Container>
@@ -191,7 +190,7 @@ export default function BeasiswaPage() {
<Container size="lg" py="xl"> <Container size="lg" py="xl">
<Group mb="sm"> <Group mb="sm">
<IconQuote size={24} color={colors["blue-button"]} /> <IconQuote size={24} color={colors["blue-button"]} />
<Title order={3}>Cerita Sukses Penerima Beasiswa</Title> <Title order={3} c={colors["blue-button"]}>Cerita Sukses Penerima Beasiswa</Title>
</Group> </Group>
<SimpleGrid cols={{ base: 1, sm: 2 }} spacing="lg"> <SimpleGrid cols={{ base: 1, sm: 2 }} spacing="lg">
@@ -219,12 +218,12 @@ export default function BeasiswaPage() {
<Container size="lg" py="xl" ta="center"> <Container size="lg" py="xl" ta="center">
<Group justify="center" mb="sm"> <Group justify="center" mb="sm">
<IconUserPlus size={28} color={colors["blue-button"]} /> <IconUserPlus size={28} color={colors["blue-button"]} />
<Title order={3}>Siap Bergabung dengan Program Ini?</Title> <Title order={3} c={colors["blue-button"]}>Siap Bergabung dengan Program Ini?</Title>
</Group> </Group>
<Text c="dimmed" mb="md"> <Text c="dimmed" mb="md">
Segera daftar dan wujudkan mimpimu bersama Desa Darmasaba. Segera daftar dan wujudkan mimpimu bersama Desa Darmasaba.
</Text> </Text>
<Button onClick={open} size="lg" radius="xl" color="blue"> <Button onClick={open} size="lg" radius="xl" bg={colors["blue-button"]}>
Daftar Sekarang Daftar Sekarang
</Button> </Button>
</Container> </Container>
@@ -269,7 +268,11 @@ export default function BeasiswaPage() {
<TextInput <TextInput
label="Kewarganegaraan" label="Kewarganegaraan"
placeholder="Masukkan kewarganegaraan" placeholder="Masukkan kewarganegaraan"
onChange={(val) => { beasiswaDesa.create.form.kewarganegaraan = val.target.value }} /> value={beasiswaDesa.create.form.kewarganegaraan || "WNI"} // tampilkan WNI kalau kosong
onChange={(e) => {
beasiswaDesa.create.form.kewarganegaraan = e.target.value;
}}
/>
<Select <Select
label="Agama" label="Agama"
placeholder="Pilih agama" placeholder="Pilih agama"

View File

@@ -1,10 +1,10 @@
'use client' 'use client'
import stateBimbinganBelajarDesa from '@/app/admin/(dashboard)/_state/pendidikan/bimbingan-belajar-desa'; import stateBimbinganBelajarDesa from '@/app/admin/(dashboard)/_state/pendidikan/bimbingan-belajar-desa';
import colors from '@/con/colors'; import colors from '@/con/colors';
import { Box, Paper, SimpleGrid, Skeleton, Stack, Text, Title, Tooltip, Divider, Badge, Group } from '@mantine/core'; import { Box, Divider, Group, Paper, SimpleGrid, Skeleton, Stack, Text, Title, Tooltip } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks'; import { useShallowEffect } from '@mantine/hooks';
import { IconBook2, IconCalendarTime, IconMapPin } from '@tabler/icons-react';
import { useProxy } from 'valtio/utils'; import { useProxy } from 'valtio/utils';
import { IconMapPin, IconCalendarTime, IconBook2 } from '@tabler/icons-react';
import BackButton from '../../desa/layanan/_com/BackButto'; import BackButton from '../../desa/layanan/_com/BackButto';
function Page() { function Page() {
@@ -55,9 +55,9 @@ function Page() {
<IconBook2 size={36} stroke={1.5} color={colors['blue-button']} /> <IconBook2 size={36} stroke={1.5} color={colors['blue-button']} />
</Box> </Box>
</Tooltip> </Tooltip>
<Badge variant="gradient" gradient={{ from: colors['blue-button'], to: 'cyan' }} size="lg" radius="sm" mb="sm"> <Title order={3} fw={700} c={colors['blue-button']} mb="xs">
{stateTujuanProgram.findById.data?.judul} {stateTujuanProgram.findById.data?.judul}
</Badge> </Title>
</Group> </Group>
<Text fz="md" style={{wordBreak: "break-word", whiteSpace: "normal"}} lh={1.6} dangerouslySetInnerHTML={{ __html: stateTujuanProgram.findById.data?.deskripsi }} /> <Text fz="md" style={{wordBreak: "break-word", whiteSpace: "normal"}} lh={1.6} dangerouslySetInnerHTML={{ __html: stateTujuanProgram.findById.data?.deskripsi }} />
</Stack> </Stack>
@@ -70,9 +70,9 @@ function Page() {
<IconMapPin size={36} stroke={1.5} color={colors['blue-button']} /> <IconMapPin size={36} stroke={1.5} color={colors['blue-button']} />
</Box> </Box>
</Tooltip> </Tooltip>
<Badge variant="gradient" gradient={{ from: colors['blue-button'], to: 'cyan' }} size="lg" radius="sm" mb="sm"> <Title order={3} fw={700} c={colors['blue-button']} mb="xs">
{stateLokasiDanJadwal.findById.data?.judul} {stateLokasiDanJadwal.findById.data?.judul}
</Badge> </Title>
</Group> </Group>
<Text fz="md" lh={1.6} style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: stateLokasiDanJadwal.findById.data?.deskripsi }} /> <Text fz="md" lh={1.6} style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: stateLokasiDanJadwal.findById.data?.deskripsi }} />
</Stack> </Stack>
@@ -85,9 +85,9 @@ function Page() {
<IconCalendarTime size={36} stroke={1.5} color={colors['blue-button']} /> <IconCalendarTime size={36} stroke={1.5} color={colors['blue-button']} />
</Box> </Box>
</Tooltip> </Tooltip>
<Badge variant="gradient" gradient={{ from: colors['blue-button'], to: 'cyan' }} size="lg" radius="sm" mb="sm"> <Title order={3} fw={700} c={colors['blue-button']} mb="xs">
{stateFasilitas.findById.data?.judul} {stateFasilitas.findById.data?.judul}
</Badge> </Title>
</Group> </Group>
<Text fz="md" lh={1.6} style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: stateFasilitas.findById.data?.deskripsi }} /> <Text fz="md" lh={1.6} style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: stateFasilitas.findById.data?.deskripsi }} />
</Stack> </Stack>

View File

@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-explicit-any */
'use client'; 'use client';
import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud'; import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud';
import colors from '@/con/colors';
import { Box, Button, Center, Container, Group, Paper, SimpleGrid, Skeleton, Stack, Text, Tooltip, ActionIcon } from '@mantine/core'; import { Box, Button, Center, Container, Group, Paper, SimpleGrid, Skeleton, Stack, Text, Tooltip, ActionIcon } from '@mantine/core';
import { IconChalkboard, IconMicroscope, IconProps, IconRefresh, IconSchool, IconInfoCircle } from '@tabler/icons-react'; import { IconChalkboard, IconMicroscope, IconProps, IconRefresh, IconSchool, IconInfoCircle } from '@tabler/icons-react';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
@@ -23,19 +24,19 @@ export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan:
const router = useTransitionRouter(); const router = useTransitionRouter();
const [stats, setStats] = useState<Stat[]>([]); const [stats, setStats] = useState<Stat[]>([]);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
// Decode the URL parameter // Decode the URL parameter
const decodedJenjangPendidikan = decodeURIComponent(jenjangPendidikan); const decodedJenjangPendidikan = decodeURIComponent(jenjangPendidikan);
const jenjangFilter = decodedJenjangPendidikan.toLowerCase() === 'semua' const jenjangFilter = decodedJenjangPendidikan.toLowerCase() === 'semua'
? undefined ? undefined
: decodedJenjangPendidikan; : decodedJenjangPendidikan;
const loadData = useCallback(async () => { const loadData = useCallback(async () => {
if (!decodedJenjangPendidikan) return; if (!decodedJenjangPendidikan) return;
try { try {
setIsLoading(true); setIsLoading(true);
// Load all data in parallel with the jenjang filter // Load all data in parallel with the jenjang filter
await Promise.all([ await Promise.all([
infoSekolahPaud.lembagaPendidikan.findMany.load(1, 100, '', jenjangFilter), infoSekolahPaud.lembagaPendidikan.findMany.load(1, 100, '', jenjangFilter),
@@ -50,7 +51,7 @@ export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan:
setStats([ setStats([
{ {
icon: IconChalkboard, icon: IconChalkboard,
jumlah: totalLembaga, jumlah: totalLembaga,
nama: 'Lembaga Pendidikan', nama: 'Lembaga Pendidikan',
@@ -119,11 +120,15 @@ export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan:
</Text> </Text>
</Box> </Box>
<Button <Button
leftSection={<IconRefresh size={16} />} leftSection={<IconRefresh color={colors['blue-button']} size={16} />}
variant="outline" variant="outline"
size="xs" size="xs"
onClick={handleRefresh} onClick={handleRefresh}
loading={stats.some(stat => stat.loading)} loading={stats.some(stat => stat.loading)}
c={colors['blue-button']}
style={{
borderColor: colors['blue-button'],
}}
> >
Segarkan Data Segarkan Data
</Button> </Button>
@@ -143,7 +148,7 @@ export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan:
aria-label="Tidak ada hasil" aria-label="Tidak ada hasil"
> >
<Center style={{ minHeight: 180, flexDirection: 'column' }}> <Center style={{ minHeight: 180, flexDirection: 'column' }}>
<Text fz="lg" fw={800} c="#2563eb"> <Text fz="lg" fw={800} c={colors['blue-button']}>
Tidak ditemukan Tidak ditemukan
</Text> </Text>
<Text c="dimmed" mt="6px"> <Text c="dimmed" mt="6px">
@@ -173,81 +178,81 @@ export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan:
style={{ width: '100%' }} style={{ width: '100%' }}
> >
<Skeleton visible={v.loading}> <Skeleton visible={v.loading}>
<Paper <Paper
p="lg" p="lg"
radius="lg" radius="lg"
style={{ style={{
background: 'white', background: 'white',
border: '1px solid #e2e8f0', border: '1px solid #e2e8f0',
boxShadow: '0 8px 28px rgba(0,0,0,0.06)', boxShadow: '0 8px 28px rgba(0,0,0,0.06)',
minHeight: 260, minHeight: 260,
}} }}
role="article" role="article"
aria-label={`${v.nama} kartu statistik`} aria-label={`${v.nama} kartu statistik`}
> >
<Stack gap="sm" mb="md"> <Stack gap="sm" mb="md">
<Center> <Center>
<Box <Box
style={{ style={{
width: 80, width: 80,
height: 80, height: 80,
borderRadius: 16, borderRadius: 16,
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center', justifyContent: 'center',
background: '#eff6ff', background: '#eff6ff',
boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.6)', boxShadow: 'inset 0 1px 0 rgba(255,255,255,0.6)',
}} }}
aria-hidden aria-hidden
> >
{React.createElement(v.icon, { {React.createElement(v.icon, {
color: '#2563eb', color: colors['blue-button'],
size: 34, size: 34,
stroke: 1.6, stroke: 1.6,
})} })}
</Box> </Box>
</Center> </Center>
<Group justify="center" align="center" gap="xs"> <Group justify="center" align="center" gap="xs">
<Stack gap={0}> <Stack gap={0}>
<Text ta={"center"} fz={{ base: 18, md: 22 }} fw={800} c="#0f172a"> <Text ta={"center"} fz={{ base: 18, md: 22 }} fw={800} c="#0f172a">
{v.jumlah.toLocaleString()} {v.jumlah.toLocaleString()}
</Text>
<Group gap={6} align="center">
<Text ta={"center"} fz="sm" fw={700} c="#2563eb">
{v.nama}
</Text> </Text>
<Tooltip label={v.helper ?? ''} position="right" withArrow> <Group gap={6} align="center">
<ActionIcon aria-label={`Info ${v.nama}`} variant="transparent" size="xs"> <Text ta={"center"} fz="sm" fw={700} c={colors['blue-button']}>
<IconInfoCircle size={16} style={{ color: '#2563eb' }} /> {v.nama}
</ActionIcon> </Text>
</Tooltip> <Tooltip label={v.helper ?? ''} position="right" withArrow>
</Group> <ActionIcon aria-label={`Info ${v.nama}`} variant="transparent" size="xs">
</Stack> <IconInfoCircle size={16} style={{ color: colors['blue-button'] }} />
</Group> </ActionIcon>
</Stack> </Tooltip>
</Group>
</Stack>
</Group>
</Stack>
<Group justify="center" mt="8px"> <Group justify="center" mt="8px">
<Button <Button
radius="xl" radius="xl"
variant="outline" variant="outline"
aria-label={`Lihat detail ${v.nama}`} aria-label={`Lihat detail ${v.nama}`}
style={{ style={{
borderColor: '#e2e8f0', borderColor: colors['blue-button'],
color: '#2563eb', color: colors['blue-button'],
paddingLeft: 20, paddingLeft: 20,
paddingRight: 20, paddingRight: 20,
}} }}
onClick={() => { onClick={() => {
if (v.nama === "Lembaga Pendidikan") router.push(`/darmasaba/pendidikan/info-sekolah/${jenjangPendidikan}/lembaga`); if (v.nama === "Lembaga Pendidikan") router.push(`/darmasaba/pendidikan/info-sekolah/${jenjangPendidikan}/lembaga`);
if (v.nama === "Siswa Terdaftar") router.push(`/darmasaba/pendidikan/info-sekolah/${jenjangPendidikan}/siswa`); if (v.nama === "Siswa Terdaftar") router.push(`/darmasaba/pendidikan/info-sekolah/${jenjangPendidikan}/siswa`);
if (v.nama === "Tenaga Pengajar") router.push(`/darmasaba/pendidikan/info-sekolah/${jenjangPendidikan}/pengajar`); if (v.nama === "Tenaga Pengajar") router.push(`/darmasaba/pendidikan/info-sekolah/${jenjangPendidikan}/pengajar`);
}} }}
> >
Lihat Detail Lihat Detail
</Button> </Button>
</Group> </Group>
</Paper> </Paper>
</Skeleton> </Skeleton>
</motion.div> </motion.div>
)) ))

View File

@@ -185,6 +185,8 @@ export default function LayoutSekolah({
radius="xl" radius="xl"
size="sm" size="sm"
variant={aktif ? 'filled' : 'light'} variant={aktif ? 'filled' : 'light'}
bg={colors['blue-button']}
c={aktif ? colors['white-1'] : 'gray'}
> >
{k} {k}
</Button> </Button>

View File

@@ -1,6 +1,7 @@
/* eslint-disable react-hooks/exhaustive-deps */ /* eslint-disable react-hooks/exhaustive-deps */
'use client' 'use client'
import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud'; import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud';
import colors from '@/con/colors';
import { import {
ActionIcon, ActionIcon,
Box, Box,
@@ -130,11 +131,15 @@ export default function SekolahPage() {
<Box> <Box>
<Group justify="start" mb="md"> <Group justify="start" mb="md">
<Button <Button
leftSection={<IconRefresh size={16} />} leftSection={<IconRefresh color={colors['blue-button']} size={16} />}
variant="outline" variant="outline"
size="xs" size="xs"
onClick={handleRefresh} onClick={handleRefresh}
loading={stats.some(stat => stat.loading)} loading={stats.some(stat => stat.loading)}
c={colors['blue-button']}
style={{
borderColor: colors['blue-button'],
}}
> >
Segarkan Data Segarkan Data
</Button> </Button>
@@ -154,7 +159,7 @@ export default function SekolahPage() {
aria-label="Tidak ada hasil" aria-label="Tidak ada hasil"
> >
<Center style={{ minHeight: 180, flexDirection: 'column' }}> <Center style={{ minHeight: 180, flexDirection: 'column' }}>
<Text fz="lg" fw={800} c="#2563eb"> <Text fz="lg" fw={800} c={colors['blue-button']}>
Tidak ditemukan Tidak ditemukan
</Text> </Text>
<Text c="dimmed" mt="6px"> <Text c="dimmed" mt="6px">
@@ -212,7 +217,7 @@ export default function SekolahPage() {
aria-hidden aria-hidden
> >
{React.createElement(v.icon, { {React.createElement(v.icon, {
color: '#2563eb', color: colors['blue-button'],
size: 34, size: 34,
stroke: 1.6, stroke: 1.6,
})} })}
@@ -225,12 +230,12 @@ export default function SekolahPage() {
{v.jumlah.toLocaleString()} {v.jumlah.toLocaleString()}
</Text> </Text>
<Group gap={6} align="center"> <Group gap={6} align="center">
<Text ta={"center"} fz="sm" fw={700} c="#2563eb"> <Text ta={"center"} fz="sm" fw={700} c={colors['blue-button']}>
{v.nama} {v.nama}
</Text> </Text>
<Tooltip label={v.helper ?? ''} position="right" withArrow> <Tooltip label={v.helper ?? ''} position="right" withArrow>
<ActionIcon aria-label={`Info ${v.nama}`} variant="transparent" size="xs"> <ActionIcon aria-label={`Info ${v.nama}`} variant="transparent" size="xs">
<IconInfoCircle size={16} style={{ color: '#2563eb' }} /> <IconInfoCircle size={16} style={{ color: colors['blue-button'] }} />
</ActionIcon> </ActionIcon>
</Tooltip> </Tooltip>
</Group> </Group>
@@ -244,8 +249,8 @@ export default function SekolahPage() {
variant="outline" variant="outline"
aria-label={`Lihat detail ${v.nama}`} aria-label={`Lihat detail ${v.nama}`}
style={{ style={{
borderColor: '#e2e8f0', borderColor: colors['blue-button'],
color: '#2563eb', color: colors['blue-button'],
paddingLeft: 20, paddingLeft: 20,
paddingRight: 20, paddingRight: 20,
}} }}

View File

@@ -74,10 +74,10 @@ function Page() {
<Stack gap="lg"> <Stack gap="lg">
<Paper p="lg" radius="xl" shadow="sm" withBorder> <Paper p="lg" radius="xl" shadow="sm" withBorder>
<Stack gap="sm"> <Stack gap="sm">
<Text fz={{ base: 'lg', md: 'xl' }} fw="bold" c={colors["blue-button"]}> <Text ta={"center"} fz={{ base: 'lg', md: 'xl' }} fw="bold" c={colors["blue-button"]}>
Tentang Informasi Publik Tentang Informasi Publik
</Text> </Text>
<Text fz={{ base: 'sm', md: 'md' }} c="dimmed"> <Text ta={"center"} 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. Daftar Informasi Publik Desa Darmasaba adalah kumpulan data yang dapat diakses oleh masyarakat sesuai dengan ketentuan peraturan yang berlaku.
</Text> </Text>
</Stack> </Stack>
@@ -117,41 +117,45 @@ function Page() {
<TableTr key={item.id}> <TableTr key={item.id}>
<TableTd ta="center">{(page - 1) * 5 + index + 1}</TableTd> <TableTd ta="center">{(page - 1) * 5 + index + 1}</TableTd>
<TableTd> <TableTd>
<Box w={150}> <Box>
<Badge variant="light" size="lg" color="blue"> <Badge variant="light" size="lg" color="blue">
{item.jenisInformasi} <Text fw={650} fz={"sm"} c={'blue'} lineClamp={1}>
{item.jenisInformasi}
</Text>
</Badge> </Badge>
</Box> </Box>
</TableTd> </TableTd>
<TableTd> <TableTd>
<Box w={150}> <Box>
<Text lineClamp={1} fz="sm" c="dark" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: item.deskripsi }} /> <Text lineClamp={1} fz="sm" c="dark" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
</Box> </Box>
</TableTd> </TableTd>
<TableTd ta="center"> <TableTd ta="center">
<Box w={150}> <Box>
{item.tanggal ? new Date(item.tanggal).toLocaleDateString('id-ID', { <Text ta={"center"}>
day: '2-digit', {item.tanggal ? new Date(item.tanggal).toLocaleDateString('id-ID', {
month: 'long', day: '2-digit',
year: 'numeric' month: 'long',
}) : '-'} year: 'numeric'
}) : '-'}
</Text>
</Box> </Box>
</TableTd> </TableTd>
<TableTd style={{ textAlign: 'center' }}> <TableTd style={{ textAlign: 'center' }}>
<Box w={150}> <Box>
<Tooltip label="Lihat Detail" withArrow> <Tooltip label="Lihat Detail" withArrow>
<Button <Button
size="xs" size="xs"
radius="md" radius="md"
variant="light" variant="light"
color="blue" color="blue"
leftSection={<IconDeviceImacCog size={16} />} leftSection={<IconDeviceImacCog size={16} />}
onClick={() => router.push(`/darmasaba/ppid/daftar-informasi-publik-desa-darmasaba/${item.id}`)} onClick={() => router.push(`/darmasaba/ppid/daftar-informasi-publik-desa-darmasaba/${item.id}`)}
> >
Detail Detail
</Button> </Button>
</Tooltip> </Tooltip>
</Box> </Box>
</TableTd> </TableTd>
</TableTr> </TableTr>
))} ))}