'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 { Anchor, Box, Center, Container, Divider, 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 { useTransitionRouter } from 'next-view-transitions'; import Link from 'next/link'; import { useEffect, useState } from 'react'; import { useProxy } from 'valtio/utils'; import BackButton from '../layanan/_com/BackButto'; 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 ( {/* Header */} Pengumuman Desa Darmasaba Informasi dan pengumuman resmi terkait kegiatan dan kebijakan Desa Darmasaba {/* Recent & Kategori */} {!recent.data?.length ? ( Tidak ada pengumuman yang ditemukan ) : ( recent.data ?.slice(0, 2) .map((item, index) => ( {item.judul} {new Date(item.createdAt).toLocaleDateString('id-ID', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric', })} {new Date(item.createdAt).toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit', timeZoneName: 'short', })} Baca Selengkapnya )) )} Kategori {stateDesaPengumuman.category.findMany.data?.map((v: any, k) => { const count = v._count?.pengumumans || 0; return ( {v.name} {count} ); })} {/* Daftar Pengumuman */} Daftar Pengumuman } w="100%" value={searchInput} onChange={(e) => setSearchInput(e.target.value)} fz={{ base: 'sm', md: 'md' }} /> {/* Loading */} {state.findMany.loading ? ( {[1, 2, 3].map((i) => ( ))} ) : !state.findMany.data?.length ? ( Tidak ada pengumuman yang ditemukan ) : ( {state.findMany.data.map((item) => (
{item.CategoryPengumuman?.name || 'Pengumuman'} {item.judul}
{new Date(item.createdAt).toLocaleDateString('id-ID', { day: 'numeric', month: 'short', year: 'numeric', })} {new Date(item.createdAt).toLocaleTimeString('id-ID', { hour: '2-digit', minute: '2-digit', })} Baca Selengkapnya →
))}
)} {/* Pagination */}
); } export default Page;