Sinkronisasi UI & API Admin - User Submenu Pengumuman
This commit is contained in:
@@ -46,11 +46,15 @@ const category = proxy({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
findMany: {
|
findMany: {
|
||||||
data: [] as Prisma.CategoryPengumumanGetPayload<{
|
data: [] as (Prisma.CategoryPengumumanGetPayload<{
|
||||||
omit: {
|
omit: {
|
||||||
isActive: true;
|
isActive: true;
|
||||||
};
|
};
|
||||||
}>[],
|
}> & {
|
||||||
|
_count: {
|
||||||
|
pengumumans: number;
|
||||||
|
};
|
||||||
|
})[],
|
||||||
loading: false,
|
loading: false,
|
||||||
async load() {
|
async load() {
|
||||||
const res = await ApiFetch.api.desa.kategoripengumuman["findMany"].get();
|
const res = await ApiFetch.api.desa.kategoripengumuman["findMany"].get();
|
||||||
|
|||||||
@@ -1,7 +1,15 @@
|
|||||||
import prisma from "@/lib/prisma";
|
import prisma from "@/lib/prisma";
|
||||||
|
|
||||||
async function kategoriPengumumanFindMany() {
|
async function kategoriPengumumanFindMany() {
|
||||||
const data = await prisma.categoryPengumuman.findMany();
|
const data = await prisma.categoryPengumuman.findMany({
|
||||||
|
include: {
|
||||||
|
_count: {
|
||||||
|
select: {
|
||||||
|
pengumumans: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
return { data };
|
return { data };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
import colors from '@/con/colors';
|
|
||||||
import { Calendar } from '@mantine/dates';
|
|
||||||
import { Stack, Box, Container, Text, Grid, Paper, GridCol, Center, SimpleGrid } from '@mantine/core';
|
|
||||||
import React from 'react';
|
|
||||||
import BackButton from '../../../layanan/_com/BackButto';
|
|
||||||
|
|
||||||
function Page() {
|
|
||||||
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="0" >
|
|
||||||
<Text fz={{ base: "2rem", md: "3.4rem" }} c={colors["blue-button"]} fw="bold" >
|
|
||||||
Jadwal Rapat
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
</Container>
|
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
|
||||||
<Grid>
|
|
||||||
<GridCol span={{ base: 12, md: 6, lg: 5, xl: 4 }} >
|
|
||||||
<Paper bg={colors['white-1']} p={'md'}>
|
|
||||||
<Center>
|
|
||||||
<Calendar size='xl' />
|
|
||||||
</Center>
|
|
||||||
</Paper>
|
|
||||||
</GridCol>
|
|
||||||
<GridCol span={{ base: 12, md: 6, lg: 7, xl: 8 }} >
|
|
||||||
<Paper bg={colors['white-1']} p={'md'}>
|
|
||||||
<SimpleGrid
|
|
||||||
cols={{
|
|
||||||
base: 1,
|
|
||||||
xl: 3,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Box>
|
|
||||||
<Text fz={'lg'} fw={'bold'} c={colors['blue-button']}>Hari Ini</Text>
|
|
||||||
<Text fz={'lg'} >Senin, 13 Februari 2023</Text>
|
|
||||||
<Text fz={'lg'} >09:00 - 12:00</Text>
|
|
||||||
<Text fz={'lg'} >12:00 - 15:00</Text>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fz={'lg'} fw={'bold'} c={colors['blue-button']}>Besok</Text>
|
|
||||||
<Text fz={'lg'} >Selasa, 14 Februari 2023</Text>
|
|
||||||
<Text fz={'lg'} >09:00 - 12:00</Text>
|
|
||||||
<Text fz={'lg'} >12:00 - 15:00</Text>
|
|
||||||
</Box>
|
|
||||||
<Box>
|
|
||||||
<Text fz={'lg'} fw={'bold'} c={colors['blue-button']}>Minggu Depan</Text>
|
|
||||||
<Text fz={'lg'} >Senin, 20 Februari 2023</Text>
|
|
||||||
<Text fz={'lg'} >09:00 - 12:00</Text>
|
|
||||||
<Text fz={'lg'} >12:00 - 15:00</Text>
|
|
||||||
</Box>
|
|
||||||
</SimpleGrid>
|
|
||||||
</Paper>
|
|
||||||
</GridCol>
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
</Stack>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Page;
|
|
||||||
@@ -1,49 +0,0 @@
|
|||||||
import colors from '@/con/colors';
|
|
||||||
import { Stack, Box, Container, Text, Image, Grid, GridCol, Paper, TextInput, Center, Button } from '@mantine/core';
|
|
||||||
import React from 'react';
|
|
||||||
import BackButton from '../../../layanan/_com/BackButto';
|
|
||||||
|
|
||||||
function Page() {
|
|
||||||
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="0" >
|
|
||||||
<Text fz={{ base: "2rem", md: "3.4rem" }} c={colors["blue-button"]} fw="bold" >
|
|
||||||
Pendaftaran UMKM
|
|
||||||
</Text>
|
|
||||||
</Stack>
|
|
||||||
</Container>
|
|
||||||
<Box px={{ base: 'md', md: 100 }}>
|
|
||||||
<Grid>
|
|
||||||
<GridCol span={{ base: 12, md: 6, lg: 7, xl: 8 }}>
|
|
||||||
<Center>
|
|
||||||
<Image src={'/api/img/market.png'} w={{ base: 300, md: 500, lg: 530, xl: 550 }} alt='' />
|
|
||||||
</Center>
|
|
||||||
</GridCol>
|
|
||||||
<GridCol span={{ base: 12, md: 6, lg: 5, xl: 4 }}>
|
|
||||||
<Paper bg={colors['white-1']} p={'md'} h={'500'}>
|
|
||||||
<Text ta={'center'} fz={{ base: "1.5rem", md: "2rem" }} c={colors["blue-button"]} fw="bold" >
|
|
||||||
Pendaftaran UMKM
|
|
||||||
</Text>
|
|
||||||
<Stack pt={20}>
|
|
||||||
<TextInput placeholder='Nama Lengkap' />
|
|
||||||
<TextInput placeholder='Alamat' />
|
|
||||||
<TextInput placeholder='No. Telepon' />
|
|
||||||
<TextInput placeholder='Email' />
|
|
||||||
<TextInput placeholder='Nama UMKM' />
|
|
||||||
<Button bg={colors['blue-button']} fullWidth>Daftar Sekarang</Button>
|
|
||||||
</Stack>
|
|
||||||
</Paper>
|
|
||||||
|
|
||||||
</GridCol>
|
|
||||||
</Grid>
|
|
||||||
</Box>
|
|
||||||
</Stack>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Page;
|
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
'use client'
|
||||||
|
import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman';
|
||||||
|
import colors from '@/con/colors';
|
||||||
|
import { Box, Container, Flex, Group, Paper, Skeleton, Stack, Text } from '@mantine/core';
|
||||||
|
import { useShallowEffect } from '@mantine/hooks';
|
||||||
|
import { useParams } from 'next/navigation';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
import BackButton from '../../../layanan/_com/BackButto';
|
||||||
|
|
||||||
|
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" >
|
||||||
|
<Flex 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>
|
||||||
|
</Flex>
|
||||||
|
<Paper bg={colors["white-1"]} p="md">
|
||||||
|
<Text fz={"md"} 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;
|
||||||
73
src/app/darmasaba/(pages)/desa/pengumuman/[name]/page.tsx
Normal file
73
src/app/darmasaba/(pages)/desa/pengumuman/[name]/page.tsx
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
'use client'
|
||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman';
|
||||||
|
import colors from '@/con/colors';
|
||||||
|
import { Box, Container, Group, Paper, Stack, Text } from '@mantine/core';
|
||||||
|
import { IconCalendar } from '@tabler/icons-react';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
import BackButton from '../../layanan/_com/BackButto';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
import { useParams } from 'next/navigation';
|
||||||
|
|
||||||
|
|
||||||
|
function Page() {
|
||||||
|
const unwrappedParams = useParams();
|
||||||
|
const kategoriState = useProxy(stateDesaPengumuman);
|
||||||
|
const categoryName = decodeURIComponent(unwrappedParams.name as string);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
kategoriState.category.findUnique.load(categoryName);
|
||||||
|
kategoriState.pengumuman.findMany.load(1, 10, '', categoryName);
|
||||||
|
}, [categoryName]);
|
||||||
|
|
||||||
|
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 align="center" gap="0" >
|
||||||
|
<Text fz={{ base: "2rem", md: "3.4rem" }} c={colors["blue-button"]} fw="bold" ta="center">
|
||||||
|
{categoryName.split('-').map(word =>
|
||||||
|
word.charAt(0).toUpperCase() + word.slice(1)
|
||||||
|
).join(' ')}
|
||||||
|
</Text>
|
||||||
|
<Text ta="center" px="md" pb={10}>
|
||||||
|
Informasi dan pengumuman resmi terkait {categoryName.split('-').join(' ')}
|
||||||
|
</Text>
|
||||||
|
</Stack>
|
||||||
|
</Container>
|
||||||
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
|
{!kategoriState.pengumuman.findMany.data?.length ? (
|
||||||
|
<Paper p="lg" radius="md" shadow="md" bg={colors["white-1"]}>
|
||||||
|
Tidak ada pengumuman yang ditemukan
|
||||||
|
</Paper>
|
||||||
|
) : kategoriState.pengumuman.findMany.data?.map((v, k) => {
|
||||||
|
return (
|
||||||
|
<Paper mb={10} key={k} withBorder p="lg" radius="md" shadow="md" bg={colors["white-1"]}>
|
||||||
|
<Text fz={'h3'}>{v.judul}</Text>
|
||||||
|
<Group style={{ color: 'black' }} pb={20}>
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconCalendar size={18} />
|
||||||
|
<Text size="sm">
|
||||||
|
{v.createdAt ? new Date(v.createdAt).toLocaleDateString('id-ID', {
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
}) : 'No date available'}
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<Text ta={'justify'}>
|
||||||
|
{v.deskripsi}
|
||||||
|
</Text>
|
||||||
|
</Paper>
|
||||||
|
)
|
||||||
|
})}
|
||||||
|
</Box>
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Page;
|
||||||
@@ -1,171 +1,299 @@
|
|||||||
|
'use client';
|
||||||
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||||
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
|
import stateDesaPengumuman from '@/app/admin/(dashboard)/_state/desa/pengumuman';
|
||||||
import colors from '@/con/colors';
|
import colors from '@/con/colors';
|
||||||
import { Anchor, Box, Container, Flex, Group, Notification, Paper, SimpleGrid, Stack, Text, TextInput, UnstyledButton } from '@mantine/core';
|
import {
|
||||||
|
Anchor,
|
||||||
|
Box,
|
||||||
|
Center,
|
||||||
|
Container,
|
||||||
|
Divider,
|
||||||
|
Flex,
|
||||||
|
Grid,
|
||||||
|
GridCol,
|
||||||
|
Group,
|
||||||
|
Notification,
|
||||||
|
Pagination,
|
||||||
|
Paper,
|
||||||
|
SimpleGrid,
|
||||||
|
Skeleton,
|
||||||
|
Stack,
|
||||||
|
Text,
|
||||||
|
TextInput,
|
||||||
|
Title,
|
||||||
|
UnstyledButton,
|
||||||
|
} from '@mantine/core';
|
||||||
import { IconCalendar, IconClock, IconSearch } from '@tabler/icons-react';
|
import { IconCalendar, IconClock, IconSearch } from '@tabler/icons-react';
|
||||||
import BackButton from '../layanan/_com/BackButto';
|
import { useTransitionRouter } from 'next-view-transitions';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import { useProxy } from 'valtio/utils';
|
||||||
|
import BackButton from '../layanan/_com/BackButto';
|
||||||
|
|
||||||
const dataKategori = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
kategori: 'Sosial & Kesehatan',
|
|
||||||
jumlah: 5,
|
|
||||||
link: '/darmasaba/desa/pengumuman/sosial-&-kesehatan'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
kategori: 'Ekonomi & UMKM',
|
|
||||||
jumlah: 7,
|
|
||||||
link: '/darmasaba/desa/pengumuman/ekonomi-&-umkm'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 3,
|
|
||||||
kategori: 'Pendidikan & Kepemudaan',
|
|
||||||
jumlah: 9,
|
|
||||||
link: '/darmasaba/desa/pengumuman/pendidikan-&-kepemudaan'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 4,
|
|
||||||
kategori: 'Lingkungan & Bencana',
|
|
||||||
jumlah: 6,
|
|
||||||
link: '/darmasaba/desa/pengumuman/lingkungan-&-bencana'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 5,
|
|
||||||
kategori: 'Adat & Budaya',
|
|
||||||
jumlah: 8,
|
|
||||||
link: '/darmasaba/desa/pengumuman/adat-&-budaya'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 6,
|
|
||||||
kategori: 'Digitalisasi Desa',
|
|
||||||
jumlah: 6,
|
|
||||||
link: '/darmasaba/desa/pengumuman/digitalisasi-desa'
|
|
||||||
},
|
|
||||||
]
|
|
||||||
const dataPenting = [
|
|
||||||
{
|
|
||||||
id: 1,
|
|
||||||
judul: 'Jadwal Rapat',
|
|
||||||
jumlah: 5,
|
|
||||||
link: '/darmasaba/desa/pengumuman/jadwal-rapat'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 2,
|
|
||||||
judul: 'Pendaftaran UMKM',
|
|
||||||
jumlah: 7,
|
|
||||||
link: '/darmasaba/desa/pengumuman/pendaftaran-umkm'
|
|
||||||
}
|
|
||||||
]
|
|
||||||
function Page() {
|
function Page() {
|
||||||
|
const router = useTransitionRouter();
|
||||||
|
|
||||||
|
// State lokal
|
||||||
|
const [search, setSearch] = useState('');
|
||||||
|
const [searchInput, setSearchInput] = useState('');
|
||||||
|
const [page, setPage] = useState(1);
|
||||||
|
|
||||||
|
const state = useProxy(stateDesaPengumuman.pengumuman);
|
||||||
|
const totalPages = state.findMany.totalPages || 1;
|
||||||
|
const recent = useProxy(stateDesaPengumuman.pengumuman.findRecent);
|
||||||
|
|
||||||
|
// ✅ Baca URL saat pertama kali mount
|
||||||
|
useEffect(() => {
|
||||||
|
const urlParams = new URLSearchParams(window.location.search);
|
||||||
|
const urlSearch = urlParams.get('search') || '';
|
||||||
|
const urlPage = parseInt(urlParams.get('page') || '1');
|
||||||
|
|
||||||
|
setSearch(urlSearch);
|
||||||
|
setSearchInput(urlSearch);
|
||||||
|
setPage(Math.max(1, urlPage)); // Pastikan page >= 1
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
// ✅ Sinkronkan URL saat `search` atau `page` berubah
|
||||||
|
useEffect(() => {
|
||||||
|
const url = new URL(window.location.href);
|
||||||
|
if (search) {
|
||||||
|
url.searchParams.set('search', search);
|
||||||
|
} else {
|
||||||
|
url.searchParams.delete('search');
|
||||||
|
}
|
||||||
|
if (page > 1) {
|
||||||
|
url.searchParams.set('page', page.toString());
|
||||||
|
} else {
|
||||||
|
url.searchParams.delete('page');
|
||||||
|
}
|
||||||
|
router.replace(url.toString());
|
||||||
|
}, [search, page, router]);
|
||||||
|
|
||||||
|
// ✅ Debounce untuk pencarian
|
||||||
|
useEffect(() => {
|
||||||
|
const timeoutId = setTimeout(() => {
|
||||||
|
if (searchInput !== search) {
|
||||||
|
setSearch(searchInput);
|
||||||
|
setPage(1); // Reset ke halaman 1 saat pencarian baru
|
||||||
|
}
|
||||||
|
}, 500);
|
||||||
|
|
||||||
|
return () => clearTimeout(timeoutId);
|
||||||
|
}, [searchInput, search]);
|
||||||
|
|
||||||
|
// ✅ Load data dari state (valtio)
|
||||||
|
useEffect(() => {
|
||||||
|
stateDesaPengumuman.category.findMany.load();
|
||||||
|
stateDesaPengumuman.pengumuman.findRecent.load();
|
||||||
|
state.findMany.load(page, 3, search);
|
||||||
|
}, [search, page]); // 🔁 Depend pada `search` dan `page`
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack pos="relative" bg={colors.Bg} py="xl" gap="md">
|
<Stack pos="relative" bg={colors.Bg} py="xl" gap="md">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<Box px={{ base: "md", md: 100 }}>
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
<BackButton />
|
<BackButton />
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
<Container size="lg" px="md">
|
<Container size="lg" px="md">
|
||||||
<Stack align="center" gap="0" >
|
<Stack align="center" gap="0">
|
||||||
<Text fz={{ base: "2rem", md: "3.4rem" }} c={colors["blue-button"]} fw="bold" ta="center">
|
<Text fz={{ base: '2rem', md: '3.4rem' }} c={colors['blue-button']} fw="bold" ta="center">
|
||||||
Pengumuman Desa Darmasaba
|
Pengumuman Desa Darmasaba
|
||||||
</Text>
|
</Text>
|
||||||
<Text ta="center" px="md" pb={10}>
|
<Text ta="center" px="md" pb={10}>
|
||||||
Informasi dan pengumuman resmi terkait kegiatan dan kebijakan Desa Darmasaba
|
Informasi dan pengumuman resmi terkait kegiatan dan kebijakan Desa Darmasaba
|
||||||
</Text>
|
</Text>
|
||||||
<TextInput
|
|
||||||
placeholder='Cari Pengumuman'
|
|
||||||
radius="lg"
|
|
||||||
leftSection={<IconSearch size={20} />}
|
|
||||||
w={{ base: "55%", md: "70%" }}
|
|
||||||
/>
|
|
||||||
</Stack>
|
</Stack>
|
||||||
</Container>
|
</Container>
|
||||||
|
|
||||||
<Box px={{ base: "md", md: 100 }}>
|
{/* Recent & Kategori */}
|
||||||
<SimpleGrid
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
cols={{
|
<SimpleGrid cols={{ base: 1, md: 2 }}>
|
||||||
base: 1,
|
<Stack>
|
||||||
md: 2,
|
{!recent.data?.length ? (
|
||||||
}}
|
<Notification withCloseButton={false} h={100}>
|
||||||
>
|
Tidak ada pengumuman yang ditemukan
|
||||||
<Notification styles={{ title: { fontWeight: "bold" } }} withCloseButton={false} title="Penting">
|
</Notification>
|
||||||
<Stack gap={"xs"}>
|
) : (
|
||||||
<Text fz={"sm"} fw={"bold"} c={"black"}>PENGUMUMAN LOWONGAN KERJA TPS3R PUDAK MESARI DESA DARMASABA</Text>
|
recent.data
|
||||||
<Text ta={"justify"} fz={"sm"} c={"black"}>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis nec arcu ac ornare. Praesent a porttitor felis. Proin varius ex nisl, in hendrerit odio tristique vel. </Text>
|
?.slice(0, 2)
|
||||||
</Stack>
|
.map((item, index) => (
|
||||||
<Flex pt={20} gap={"md"} justify={"space-between"}>
|
<Notification
|
||||||
<Group style={{ color: 'black' }}>
|
key={item.id}
|
||||||
<Group gap="xs">
|
color={index === 0 ? undefined : 'yellow'}
|
||||||
<IconCalendar size={18} />
|
styles={{ title: { fontWeight: 'bold' } }}
|
||||||
<Text size="sm">Kamis, 13 Januari 2025</Text>
|
withCloseButton={false}
|
||||||
</Group>
|
title={item.CategoryPengumuman?.name || 'Pengumuman'}
|
||||||
<Group gap="xs">
|
>
|
||||||
<IconClock size={18} />
|
<Stack gap={"xs"}>
|
||||||
<Text size="sm">09:00 WITA</Text>
|
<Text fz="sm" fw="bold" c="black" style={{ textTransform: 'uppercase' }}>
|
||||||
</Group>
|
{item.judul}
|
||||||
</Group>
|
</Text>
|
||||||
<Anchor>
|
<Text ta="justify" fz="sm" c="black" lineClamp={3} dangerouslySetInnerHTML={{ __html: item.content }} />
|
||||||
<Text fs={'unset'} c={colors["blue-button"]} fz={"sm"}>Baca Selengkapnya</Text>
|
</Stack>
|
||||||
</Anchor>
|
<Flex pt={20} gap="md" justify="space-between">
|
||||||
</Flex>
|
<Group style={{ color: 'black' }}>
|
||||||
</Notification>
|
<Group gap="xs">
|
||||||
<Paper p={"md"}>
|
<IconCalendar size={18} />
|
||||||
<Stack gap={"xs"}>
|
<Text size="sm">
|
||||||
<Text fw={"bold"} fz={"lg"} c={colors['blue-button']}>Kategori</Text>
|
{new Date(item.createdAt).toLocaleDateString('id-ID', {
|
||||||
{dataKategori.map((v, k) => {
|
weekday: 'long',
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'long',
|
||||||
|
year: 'numeric',
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
<Group gap="xs">
|
||||||
|
<IconClock size={18} />
|
||||||
|
<Text size="sm">
|
||||||
|
{new Date(item.createdAt).toLocaleTimeString('id-ID', {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
timeZoneName: 'short',
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<Anchor variant="transparent" href={`/darmasaba/desa/pengumuman/${item.CategoryPengumuman?.name}/${item.id}`}>
|
||||||
|
<Text fs="unset" c={colors['blue-button']} fz="sm">
|
||||||
|
Baca Selengkapnya
|
||||||
|
</Text>
|
||||||
|
</Anchor>
|
||||||
|
</Flex>
|
||||||
|
</Notification>
|
||||||
|
))
|
||||||
|
)}
|
||||||
|
</Stack>
|
||||||
|
|
||||||
|
<Paper p="md">
|
||||||
|
<Stack gap="xs">
|
||||||
|
<Text fw="bold" fz="lg" c={colors['blue-button']}>
|
||||||
|
Kategori
|
||||||
|
</Text>
|
||||||
|
{stateDesaPengumuman.category.findMany.data?.map((v: any, k) => {
|
||||||
|
const count = v._count?.pengumumans || 0;
|
||||||
return (
|
return (
|
||||||
<UnstyledButton component={Link} href={v.link} key={k}>
|
<UnstyledButton component={Link} href={`/darmasaba/desa/pengumuman/${v.name}`} key={k}>
|
||||||
<Paper bg={colors["BG-trans"]} p={5}>
|
<Paper bg={colors['BG-trans']} p={5}>
|
||||||
<Group px={3} justify={"space-between"}>
|
<Group px={3} justify="space-between">
|
||||||
<Text fz={"md"} c={"black"}>{v.kategori}</Text>
|
<Text fz="md" c="black">
|
||||||
<Text fz={"md"} c={"black"}>{v.jumlah}</Text>
|
{v.name}
|
||||||
|
</Text>
|
||||||
|
<Text fz="md" c="black">
|
||||||
|
{count}
|
||||||
|
</Text>
|
||||||
</Group>
|
</Group>
|
||||||
</Paper>
|
</Paper>
|
||||||
</UnstyledButton>
|
</UnstyledButton>
|
||||||
)
|
);
|
||||||
})}
|
|
||||||
</Stack>
|
|
||||||
</Paper>
|
|
||||||
<Notification color='yellow' styles={{ title: { fontWeight: "bold" } }} withCloseButton={false} title="Informasi">
|
|
||||||
<Stack gap={"xs"}>
|
|
||||||
<Text fz={"sm"} fw={"bold"} c={"black"}>LELANG PEMASANGAN CCTV DESA DARMASABA</Text>
|
|
||||||
<Text ta={"justify"} fz={"sm"} c={"black"}>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce sagittis nec arcu ac ornare. Praesent a porttitor felis. Proin varius ex nisl, in hendrerit odio tristique vel. </Text>
|
|
||||||
</Stack>
|
|
||||||
<Flex pt={20} gap={"md"} justify={"space-between"}><Group style={{ color: 'black' }}>
|
|
||||||
<Group gap="xs">
|
|
||||||
<IconCalendar size={18} />
|
|
||||||
<Text size="sm">Kamis, 2 Februari 2025</Text>
|
|
||||||
</Group>
|
|
||||||
<Group gap="xs">
|
|
||||||
<IconClock size={18} />
|
|
||||||
<Text size="sm">10:00 WITA</Text>
|
|
||||||
</Group>
|
|
||||||
</Group>
|
|
||||||
<Anchor>
|
|
||||||
<Text fs={'unset'} c={colors["blue-button"]} fz={"sm"}>Baca Selengkapnya</Text>
|
|
||||||
</Anchor>
|
|
||||||
</Flex>
|
|
||||||
</Notification>
|
|
||||||
<Paper p={"md"}>
|
|
||||||
<Stack gap={"xs"}>
|
|
||||||
<Text fw={"bold"} fz={"lg"} c={colors['blue-button']}>Pengumuman Penting</Text>
|
|
||||||
{dataPenting.map((v, k) => {
|
|
||||||
return (
|
|
||||||
<UnstyledButton component={Link} href={v.link} key={k}>
|
|
||||||
<Paper bg={colors["BG-trans"]} p={5}>
|
|
||||||
<Group px={3} justify={"space-between"}>
|
|
||||||
<Text fz={"md"} c={"black"}>{v.judul}</Text>
|
|
||||||
<Text fz={"md"} c={"black"}>{v.jumlah}</Text>
|
|
||||||
</Group>
|
|
||||||
</Paper>
|
|
||||||
</UnstyledButton>
|
|
||||||
)
|
|
||||||
})}
|
})}
|
||||||
</Stack>
|
</Stack>
|
||||||
</Paper>
|
</Paper>
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
</Box>
|
</Box>
|
||||||
|
|
||||||
|
{/* Daftar Pengumuman */}
|
||||||
|
<Box px={{ base: 'md', md: 100 }}>
|
||||||
|
<Stack gap="xs">
|
||||||
|
<Divider mb={10} color={colors['blue-button']} />
|
||||||
|
<Grid>
|
||||||
|
<GridCol span={{ base: 12, md: 8 }}>
|
||||||
|
<Title order={3}>Daftar Pengumuman</Title>
|
||||||
|
</GridCol>
|
||||||
|
<GridCol span={{ base: 12, md: 4 }}>
|
||||||
|
<TextInput
|
||||||
|
placeholder="Cari Pengumuman"
|
||||||
|
radius="lg"
|
||||||
|
leftSection={<IconSearch size={20} />}
|
||||||
|
w="100%"
|
||||||
|
value={searchInput}
|
||||||
|
onChange={(e) => setSearchInput(e.target.value)}
|
||||||
|
/>
|
||||||
|
</GridCol>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
{/* Loading */}
|
||||||
|
{state.findMany.loading ? (
|
||||||
|
<SimpleGrid cols={{ base: 1, md: 3 }}>
|
||||||
|
{[1, 2, 3].map((i) => (
|
||||||
|
<Skeleton key={i} h={400} />
|
||||||
|
))}
|
||||||
|
</SimpleGrid>
|
||||||
|
) : !state.findMany.data?.length ? (
|
||||||
|
<Notification withCloseButton={false} h={100}>
|
||||||
|
Tidak ada pengumuman yang ditemukan
|
||||||
|
</Notification>
|
||||||
|
) : (
|
||||||
|
<SimpleGrid cols={{ base: 1, md: 3 }} spacing="lg" verticalSpacing="lg">
|
||||||
|
{state.findMany.data.map((item) => (
|
||||||
|
<Paper key={item.id} p="md" withBorder radius="md" h="100%">
|
||||||
|
<Stack h="100%" justify="space-between">
|
||||||
|
<div>
|
||||||
|
<Text fw={600} c={colors['blue-button']} mb={5}>
|
||||||
|
{item.CategoryPengumuman?.name || 'Pengumuman'}
|
||||||
|
</Text>
|
||||||
|
<Text fz="lg" fw={700} mb="sm" lineClamp={2} style={{ textTransform: 'uppercase' }}>
|
||||||
|
{item.judul}
|
||||||
|
</Text>
|
||||||
|
<Text
|
||||||
|
fz="sm"
|
||||||
|
c="dimmed"
|
||||||
|
lineClamp={4}
|
||||||
|
dangerouslySetInnerHTML={{ __html: item.content }}
|
||||||
|
mb="md"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<Group mb="sm" c="dimmed">
|
||||||
|
<Group gap={5}>
|
||||||
|
<IconCalendar size={16} />
|
||||||
|
<Text size="xs">
|
||||||
|
{new Date(item.createdAt).toLocaleDateString('id-ID', {
|
||||||
|
day: 'numeric',
|
||||||
|
month: 'short',
|
||||||
|
year: 'numeric',
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
<Group gap={5}>
|
||||||
|
<IconClock size={16} />
|
||||||
|
<Text size="xs">
|
||||||
|
{new Date(item.createdAt).toLocaleTimeString('id-ID', {
|
||||||
|
hour: '2-digit',
|
||||||
|
minute: '2-digit',
|
||||||
|
})}
|
||||||
|
</Text>
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
<Anchor variant="transparent" href={`/darmasaba/desa/pengumuman/${item.CategoryPengumuman?.name}/${item.id}`}>
|
||||||
|
<Text fw={600} c={colors['blue-button']} size="sm">
|
||||||
|
Baca Selengkapnya →
|
||||||
|
</Text>
|
||||||
|
</Anchor>
|
||||||
|
</div>
|
||||||
|
</Stack>
|
||||||
|
</Paper>
|
||||||
|
))}
|
||||||
|
</SimpleGrid>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* Pagination */}
|
||||||
|
<Center mt="xl">
|
||||||
|
<Pagination
|
||||||
|
total={totalPages}
|
||||||
|
value={page}
|
||||||
|
onChange={setPage}
|
||||||
|
siblings={1}
|
||||||
|
boundaries={1}
|
||||||
|
withEdges
|
||||||
|
/>
|
||||||
|
</Center>
|
||||||
|
</Stack>
|
||||||
|
</Box>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Page;
|
export default Page;
|
||||||
Reference in New Issue
Block a user