Merge pull request 'nico/28-okt-25' (#4) from nico/28-okt-25 into staging

Reviewed-on: http://wibugit.wibudev.com/wibu/desa-darmasaba/pulls/4
This commit is contained in:
2025-10-28 23:05:26 +08:00
27 changed files with 629 additions and 337 deletions

View File

@@ -2,7 +2,7 @@
'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, 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 { useTransitionRouter } from 'next-view-transitions';
import { useEffect, useState } from 'react';
@@ -114,7 +114,6 @@ function Page() {
</Text>
</Box>
<Group justify="center">
<Tooltip label="Lihat detail potensi" withArrow>
<Button
radius="xl"
size="md"
@@ -126,7 +125,6 @@ function Page() {
>
Lihat Detail
</Button>
</Tooltip>
</Group>
</Stack>
</BackgroundImage>

View File

@@ -95,7 +95,7 @@ function ProfilPerbekel() {
<Box>
<Stack 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>
</Stack>
<Text
@@ -111,7 +111,7 @@ function ProfilPerbekel() {
<Box>
<Stack 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>
</Stack>
<Text
@@ -138,7 +138,7 @@ function ProfilPerbekel() {
<Stack gap="xl">
<Box>
<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>
</Stack>
<Text
@@ -152,7 +152,7 @@ function ProfilPerbekel() {
<Box>
<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>
</Stack>
<Box px={10}>

View File

@@ -52,7 +52,7 @@ function Page() {
<Box px={{ base: 'md', md: 100 }}>
<BackButton />
</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"}>
Lowongan Kerja Lokal
</Text>

View File

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

View File

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

View File

@@ -75,18 +75,18 @@ function AdministrasiOnline() {
<Title order={3}>Ajukan Administrasi Online</Title>
<TextInput
label={<Text fz="sm" fw="bold">Nama</Text>}
placeholder="masukkan nama"
placeholder="Masukkan nama"
onChange={(val) => (state.administrasiOnline.create.form.name = val.target.value)}
/>
<TextInput
label={<Text fz="sm" fw="bold">Alamat</Text>}
placeholder="masukkan alamat"
placeholder="Masukkan alamat"
onChange={(val) => (state.administrasiOnline.create.form.alamat = val.target.value)}
/>
<TextInput
type="number"
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)}
/>
<Select
@@ -95,7 +95,7 @@ function AdministrasiOnline() {
state.administrasiOnline.create.form.jenisLayananId = val ?? "";
}}
label={<Text fw={"bold"} fz={"sm"}>Jenis Layanan</Text>}
placeholder="Pilih kategori produk"
placeholder="Pilih jenis layanan"
data={
state.jenisLayanan.findMany.data?.map((v) => ({
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 */
'use client'
import stateDashboardBerita from '@/app/admin/(dashboard)/_state/desa/berita';
import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman';
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 relativeTime from 'dayjs/plugin/relativeTime';
import { useEffect } from 'react';
import { useProxy } from 'valtio/utils';
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);
function InformasiDesa() {
const stateBerita = useProxy(stateDashboardBerita.berita)
const statePengumuman = useProxy(stateDesaPengumuman.pengumuman)
const router = useTransitionRouter()
const stateBerita = useProxy(stateDashboardBerita.berita);
const statePengumuman = useProxy(stateDesaPengumuman.pengumuman);
useEffect(() => {
stateBerita.findFirst.load();
@@ -23,116 +26,216 @@ function InformasiDesa() {
statePengumuman.findRecent.load();
}, []);
const dataBerita = stateBerita.findFirst.data
const dataPengumuman = statePengumuman.findFirst.data
const dataBerita = stateBerita.findFirst.data;
const dataPengumuman = statePengumuman.findFirst.data;
return (
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
<Stack pos="relative" bg={colors.Bg} py="xl" gap={22}>
<Box px={{ base: 'md', md: 100 }}>
<BackButton />
</Box>
<Box px={{ base: 'md', md: 100 }} >
<Text ta={"center"} fz={{ base: "h1", md: "2.5rem" }} c={colors["blue-button"]} fw={"bold"}>
<Box px={{ base: 'md', md: 100 }}>
<Title ta="center" fz={{ base: 'h1', md: '2.5rem' }} c={colors['blue-button']} fw="bold">
Informasi Desa
</Text>
</Title>
</Box>
<Box px={{ base: "md", md: 100 }}>
<Stack gap={10}>
<Box px={{ base: 'md', md: 100 }}>
<Stack gap={30}>
{/* === BERITA UTAMA === */}
{dataBerita && (
<Paper shadow="md" radius="md" p="md">
<Grid>
<GridCol span={{ md: 6, base: 12 }}>
<motion.div
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
style={{ cursor: "pointer" }}
onClick={() => router.push(`/darmasaba/inovasi/layanan-online-desa/informasi-desa/detail-berita/${dataBerita.id}`)}
>
<Paper shadow="md" radius="lg" p="lg" withBorder>
<Grid align="center" gutter="xl">
<GridCol span={{ base: 12, md: 6 }}>
<Image
src={dataBerita.image?.link || "/fallback.jpg"}
src={dataBerita.image?.link || '/fallback.jpg'}
alt={dataBerita.judul}
radius="md"
fit="cover"
height={250}
maw={600}
height={280}
loading="lazy"
style={{ objectPosition: 'center' }}
/>
</GridCol>
<GridCol span={{ md: 6, base: 12 }}>
<Box>
<Text fz="sm" c="dimmed">{dataBerita.kategoriBerita?.name} {dayjs(dataBerita.createdAt).fromNow()}</Text>
<Title order={1} fw="bold">{dataBerita.judul}</Title>
<Text ta={"justify"} mt="xs" fz="md" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: dataBerita.content }} />
</Box>
<GridCol span={{ base: 12, md: 6 }}>
<Stack gap="xs">
<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>
<Grid>
{/* === BERITA TERBARU === */}
<Stack>
<Title order={3} fw={700}>
Berita Terbaru
</Title>
<Grid gutter="xl">
{stateBerita.findRecent.data.map((item) => (
<GridCol span={{ base: 12, sm: 6, md: 3 }} key={item.id}>
<Card shadow="sm" radius="md" withBorder h="100%">
<motion.div
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
style={{ cursor: "pointer" }}
onClick={() => router.push(`/darmasaba/inovasi/layanan-online-desa/informasi-desa/detail-berita/${item.id}`)}
>
<Card
shadow="sm"
radius="md"
withBorder
h="100%"
>
<Card.Section>
<Image
src={item.image?.link || "/placeholder.jpg"}
src={item.image?.link || '/placeholder.jpg'}
alt={item.judul}
height={160} // gambar fix height
height={160}
fit="cover"
radius="sm"
loading="lazy"
/>
</Card.Section>
<Stack gap="xs" mt="sm">
<Text fw={600} lineClamp={2}>
{item.judul}
</Text>
<Text size="sm" color="dimmed" lineClamp={2}>
{item.deskripsi}
</Text>
<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>
))}
</Grid>
</Stack>
<Divider color={colors['blue-button']} my="md" />
<Grid>
<GridCol span={{ md: 6, base: 12 }}>
<Divider color={colors['blue-button']} my="lg" />
{/* === PENGUMUMAN === */}
<Grid gutter="xl" align="stretch">
<GridCol span={{ base: 12, md: 6 }}>
{dataPengumuman && (
<Paper h={"97%"} shadow="md" radius="md" p="md">
<Stack gap={"xs"}>
<Title order={1} fw="bold">{dataPengumuman.judul}</Title>
<Text fz="sm" c="dimmed">{dataPengumuman.CategoryPengumuman?.name} {dayjs(dataPengumuman.createdAt).fromNow()}</Text>
<Box>
<Text ta={"justify"} mt="xs" fz="md" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: dataPengumuman.content }} />
</Box>
<motion.div
onClick={() => router.push(`/darmasaba/inovasi/layanan-online-desa/informasi-desa/detail-pengumuman/${dataPengumuman.id}`)}
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
style={{ cursor: "pointer" }}
>
<Paper shadow="md" radius="lg" p="lg" h="100%" withBorder>
<Stack gap="xs">
<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 span={{ md: 6, base: 12 }}>
<Stack py={10}>
<Title order={3}>Pengumuman Terbaru</Title>
<Grid>
<GridCol span={{ base: 12, md: 6 }}>
<Stack>
<Title order={3} fw={700}>
Pengumuman Terbaru
</Title>
<Grid gutter="lg">
{statePengumuman.findRecent.data.map((item) => (
<GridCol span={{ base: 12, sm: 8, md: 6 }} key={item.id}>
<Card shadow="sm" radius="md" withBorder h="100%">
<Stack gap="xs" mt="sm">
<GridCol span={{ base: 12, sm: 6 }} key={item.id}>
<motion.div
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
style={{ cursor: "pointer" }}
onClick={() => router.push(`/darmasaba/inovasi/layanan-online-desa/informasi-desa/detail-pengumuman/${item.id}`)}
>
<Card
shadow="xs"
radius="md"
withBorder
h="100%"
p="md"
style={{ transition: '0.2s ease' }}
className="hover:shadow-md"
>
<Stack gap="xs">
<Text fw={600} lineClamp={2}>
{item.judul}
</Text>
<Text size="sm" color="dimmed" lineClamp={2}>
{item.deskripsi}
</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>
))}
</Grid>
</Stack>
</GridCol>
</Grid>

View File

@@ -100,33 +100,33 @@ function PengaduanMasyarakat() {
<Title order={3}>Ajukan Pengaduan Masyarakat</Title>
<TextInput
label={<Text fz="sm" fw="bold">Nama</Text>}
placeholder="masukkan nama"
placeholder="Masukkan nama"
onChange={(val) => (state.pengaduanMasyarakat.create.form.name = val.target.value)}
/>
<TextInput
label={<Text fz="sm" fw="bold">Email</Text>}
placeholder="masukkan email"
placeholder="Masukkan email"
onChange={(val) => (state.pengaduanMasyarakat.create.form.email = val.target.value)}
/>
<TextInput
type="number"
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)}
/>
<TextInput
label={<Text fz="sm" fw="bold">NIK</Text>}
placeholder="masukkan nik"
placeholder="Masukkan nik"
onChange={(val) => (state.pengaduanMasyarakat.create.form.nik = val.target.value)}
/>
<TextInput
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)}
/>
<TextInput
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)}
/>
<Box>
@@ -144,7 +144,7 @@ function PengaduanMasyarakat() {
state.pengaduanMasyarakat.create.form.jenisPengaduanId = val ?? "";
}}
label={<Text fw={"bold"} fz={"sm"}>Jenis Pengaduan</Text>}
placeholder="Pilih kategori produk"
placeholder="Pilih jenis pengaduan"
data={
state.jenisPengaduan.findMany.data?.map((v) => ({
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" />
</Card.Section>
<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">
<IconCalendar size={16} color={colors['blue-button']} />
<IconCalendar size={16} color='gray' />
<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}>
<Text fz="md" lineClamp={3}>
{item.content}
</Text>
<Group justify="flex-start">

View File

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

View File

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

View File

@@ -73,7 +73,6 @@ function DetailInfoWabahPenyakitUser() {
<Text fz="lg" fw="bold">Deskripsi</Text>
<Text
fz="md"
c="dimmed"
dangerouslySetInnerHTML={{ __html: data.deskripsiLengkap || '-' }}
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}>
Kontak Darurat
</Text>
<Text c="dimmed" fz="md" mt={4}>
<Text fz="md" mt={4}>
Hubungi layanan penting dengan cepat dan mudah
</Text>
</GridCol>
@@ -128,7 +128,7 @@ function Page() {
<Text ta="center" fw={700} fz="lg" c={colors['blue-button']}>
{v.name}
</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 }} />
</Text>
<Button

View File

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

View File

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

View File

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

View File

@@ -93,20 +93,23 @@ function Page() {
<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>
<Stack gap={6}>
<Group gap="xs" align="flex-start" wrap="nowrap">
<Box pt={2}><IconMapPin size={16} /></Box>
<Text fz="sm" c="dimmed">{v.alamat}</Text>
</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>
</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>
</Group>
</Stack>
<Anchor
href={`/darmasaba/kesehatan/puskesmas/${v.id}`}
fz="sm"

View File

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

View File

@@ -1,13 +1,13 @@
'use client'
import beasiswaDesaState from '@/app/admin/(dashboard)/_state/pendidikan/beasiswa-desa';
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 { IconArrowRight, IconCoin, IconInfoCircle, IconSchool, IconUsers } from '@tabler/icons-react';
import { useTransitionRouter } from 'next-view-transitions';
import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
import { useTransitionRouter } from 'next-view-transitions';
const dataBeasiswa = [
{ id: 1, nama: 'Penerima Beasiswa', jumlah: '250+', icon: IconUsers },
@@ -27,7 +27,7 @@ function Page() {
tempatLahir: "",
tanggalLahir: "",
jenisKelamin: "",
kewarganegaraan: "",
kewarganegaraan: "WNI",
agama: "",
alamatKTP: "",
alamatDomisili: "",
@@ -50,9 +50,21 @@ function Page() {
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 nextStep = () => setActive((current) => (current < 5 ? current + 1 : current));
const prevStep = () => setActive((current) => (current > 0 ? current - 1 : current));
useShallowEffect(() => {
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) {
return (
@@ -115,7 +127,7 @@ function Page() {
{data.map((v, k) => (
<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>
<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>
))}
</SimpleGrid>
@@ -139,19 +151,22 @@ function Page() {
Timeline Pendaftaran
</Title>
<Center>
<Stepper mt={20} active={active} onStepClick={setActive} orientation="vertical" allowNextStepsSelect={false}>
<StepperStep label="1 Maret 2025" description="Pembukaan Pendaftaran" />
<StepperStep label="15 Maret 2025" description="Seleksi Administrasi" />
<StepperStep label="1 April 2025" description="Tes Potensi Akademik" />
<StepperStep label="15 April 2025" description="Wawancara" />
<StepperStep label="1 Mei 2025" description="Pengumuman Hasil" />
<Stepper
mt={20}
active={active}
onStepClick={setActive}
orientation="vertical"
allowNextStepsSelect={false}
>
{timeline.map((item, index) => (
<Stepper.Step
key={index}
label={item.label}
description={item.desc}
/>
))}
</Stepper>
</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>
<Modal
@@ -194,7 +209,11 @@ function Page() {
<TextInput
label="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
label="Agama"
placeholder="Pilih agama"

View File

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

View File

@@ -1,10 +1,10 @@
'use client'
import stateBimbinganBelajarDesa from '@/app/admin/(dashboard)/_state/pendidikan/bimbingan-belajar-desa';
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 { IconBook2, IconCalendarTime, IconMapPin } from '@tabler/icons-react';
import { useProxy } from 'valtio/utils';
import { IconMapPin, IconCalendarTime, IconBook2 } from '@tabler/icons-react';
import BackButton from '../../desa/layanan/_com/BackButto';
function Page() {
@@ -55,9 +55,9 @@ function Page() {
<IconBook2 size={36} stroke={1.5} color={colors['blue-button']} />
</Box>
</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}
</Badge>
</Title>
</Group>
<Text fz="md" style={{wordBreak: "break-word", whiteSpace: "normal"}} lh={1.6} dangerouslySetInnerHTML={{ __html: stateTujuanProgram.findById.data?.deskripsi }} />
</Stack>
@@ -70,9 +70,9 @@ function Page() {
<IconMapPin size={36} stroke={1.5} color={colors['blue-button']} />
</Box>
</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}
</Badge>
</Title>
</Group>
<Text fz="md" lh={1.6} style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: stateLokasiDanJadwal.findById.data?.deskripsi }} />
</Stack>
@@ -85,9 +85,9 @@ function Page() {
<IconCalendarTime size={36} stroke={1.5} color={colors['blue-button']} />
</Box>
</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}
</Badge>
</Title>
</Group>
<Text fz="md" lh={1.6} style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: stateFasilitas.findById.data?.deskripsi }} />
</Stack>

View File

@@ -1,6 +1,7 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
'use client';
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 { IconChalkboard, IconMicroscope, IconProps, IconRefresh, IconSchool, IconInfoCircle } from '@tabler/icons-react';
import { motion } from 'framer-motion';
@@ -119,11 +120,15 @@ export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan:
</Text>
</Box>
<Button
leftSection={<IconRefresh size={16} />}
leftSection={<IconRefresh color={colors['blue-button']} size={16} />}
variant="outline"
size="xs"
onClick={handleRefresh}
loading={stats.some(stat => stat.loading)}
c={colors['blue-button']}
style={{
borderColor: colors['blue-button'],
}}
>
Segarkan Data
</Button>
@@ -143,7 +148,7 @@ export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan:
aria-label="Tidak ada hasil"
>
<Center style={{ minHeight: 180, flexDirection: 'column' }}>
<Text fz="lg" fw={800} c="#2563eb">
<Text fz="lg" fw={800} c={colors['blue-button']}>
Tidak ditemukan
</Text>
<Text c="dimmed" mt="6px">
@@ -201,7 +206,7 @@ export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan:
aria-hidden
>
{React.createElement(v.icon, {
color: '#2563eb',
color: colors['blue-button'],
size: 34,
stroke: 1.6,
})}
@@ -214,12 +219,12 @@ export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan:
{v.jumlah.toLocaleString()}
</Text>
<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}
</Text>
<Tooltip label={v.helper ?? ''} position="right" withArrow>
<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>
</Tooltip>
</Group>
@@ -233,8 +238,8 @@ export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan:
variant="outline"
aria-label={`Lihat detail ${v.nama}`}
style={{
borderColor: '#e2e8f0',
color: '#2563eb',
borderColor: colors['blue-button'],
color: colors['blue-button'],
paddingLeft: 20,
paddingRight: 20,
}}

View File

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

View File

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

View File

@@ -74,10 +74,10 @@ function Page() {
<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"]}>
<Text ta={"center"} fz={{ base: 'lg', md: 'xl' }} fw="bold" c={colors["blue-button"]}>
Tentang Informasi Publik
</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.
</Text>
</Stack>
@@ -117,28 +117,32 @@ function Page() {
<TableTr key={item.id}>
<TableTd ta="center">{(page - 1) * 5 + index + 1}</TableTd>
<TableTd>
<Box w={150}>
<Box>
<Badge variant="light" size="lg" color="blue">
<Text fw={650} fz={"sm"} c={'blue'} lineClamp={1}>
{item.jenisInformasi}
</Text>
</Badge>
</Box>
</TableTd>
<TableTd>
<Box w={150}>
<Text lineClamp={1} fz="sm" c="dark" style={{wordBreak: "break-word", whiteSpace: "normal"}} dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
<Box>
<Text lineClamp={1} fz="sm" c="dark" style={{ wordBreak: "break-word", whiteSpace: "normal" }} dangerouslySetInnerHTML={{ __html: item.deskripsi }} />
</Box>
</TableTd>
<TableTd ta="center">
<Box w={150}>
<Box>
<Text ta={"center"}>
{item.tanggal ? new Date(item.tanggal).toLocaleDateString('id-ID', {
day: '2-digit',
month: 'long',
year: 'numeric'
}) : '-'}
</Text>
</Box>
</TableTd>
<TableTd style={{ textAlign: 'center' }}>
<Box w={150}>
<Box>
<Tooltip label="Lihat Detail" withArrow>
<Button
size="xs"