diff --git a/src/app/admin/(dashboard)/_state/landing-page/apbdes.ts b/src/app/admin/(dashboard)/_state/landing-page/apbdes.ts index 12f09393..c780b1a9 100644 --- a/src/app/admin/(dashboard)/_state/landing-page/apbdes.ts +++ b/src/app/admin/(dashboard)/_state/landing-page/apbdes.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import ApiFetch from "@/lib/api-fetch"; import { Prisma } from "@prisma/client"; import { toast } from "react-toastify"; @@ -50,18 +51,50 @@ const apbdes = proxy({ }, }, findMany: { - data: null as Array< - Prisma.APBDesGetPayload<{ - include: { - image: true; - file: true; - }; - }> - > | null, - async load() { - const res = await ApiFetch.api.landingpage.apbdes["find-many"].get(); - if (res.status === 200) { - apbdes.findMany.data = res.data?.data ?? []; + data: null as + | Prisma.APBDesGetPayload<{ + include: { + image: true; + file: true; + }; + }>[] + | null, + page: 1, + totalPages: 1, + total: 0, + loading: false, + search: "", + load: async (page = 1, limit = 10, search = "") => { // Change to arrow function + apbdes.findMany.loading = true; // Use the full path to access the property + apbdes.findMany.page = page; + apbdes.findMany.search = search; + try { + const query: any = { page, limit }; + if (search) query.search = search; + + const res = await ApiFetch.api.landingpage.apbdes[ + "findMany" + ].get({ + query + }); + + if (res.status === 200 && res.data?.success) { + apbdes.findMany.data = res.data.data || []; + apbdes.findMany.total = res.data.total || 0; + apbdes.findMany.totalPages = res.data.totalPages || 1; + } else { + console.error("Failed to load pegawai:", res.data?.message); + apbdes.findMany.data = []; + apbdes.findMany.total = 0; + apbdes.findMany.totalPages = 1; + } + } catch (error) { + console.error("Error loading pegawai:", error); + apbdes.findMany.data = []; + apbdes.findMany.total = 0; + apbdes.findMany.totalPages = 1; + } finally { + apbdes.findMany.loading = false; } }, }, diff --git a/src/app/admin/(dashboard)/_state/landing-page/desa-anti-korupsi.ts b/src/app/admin/(dashboard)/_state/landing-page/desa-anti-korupsi.ts index e3f0dc85..c5fe9818 100644 --- a/src/app/admin/(dashboard)/_state/landing-page/desa-anti-korupsi.ts +++ b/src/app/admin/(dashboard)/_state/landing-page/desa-anti-korupsi.ts @@ -60,16 +60,22 @@ const desaAntikorupsi = proxy({ totalPages: 1, total: 0, loading: false, - load: async (page = 1, limit = 10) => { // Change to arrow function - desaAntikorupsi.findMany.loading = true; // Use the full path to access the property + search: "", + load: async (page = 1, limit = 10, search = "") => { + // Change to arrow function + desaAntikorupsi.findMany.loading = true; // Use the full path to access the property desaAntikorupsi.findMany.page = page; + desaAntikorupsi.findMany.search = search; try { + const query: any = { page, limit }; + if (search) query.search = search; + const res = await ApiFetch.api.landingpage.desaantikorupsi[ "findMany" ].get({ - query: { page, limit }, + query, }); - + if (res.status === 200 && res.data?.success) { desaAntikorupsi.findMany.data = res.data.data || []; desaAntikorupsi.findMany.total = res.data.total || 0; @@ -305,20 +311,25 @@ const kategoriDesaAntiKorupsi = proxy({ totalPages: 1, total: 0, loading: false, - load: async (page = 1, limit = 10) => { // Change to arrow function - kategoriDesaAntiKorupsi.findMany.loading = true; // Use the full path to access the property + search: "", + load: async (page = 1, limit = 10, search = "") => { + // Change to arrow function + kategoriDesaAntiKorupsi.findMany.loading = true; // Use the full path to access the property kategoriDesaAntiKorupsi.findMany.page = page; + kategoriDesaAntiKorupsi.findMany.search = search; try { - const res = await ApiFetch.api.landingpage.kategoridak[ - "findMany" - ].get({ - query: { page, limit }, + const query: any = { page, limit }; + if (search) query.search = search; + + const res = await ApiFetch.api.landingpage.kategoridak["findMany"].get({ + query, }); - + if (res.status === 200 && res.data?.success) { kategoriDesaAntiKorupsi.findMany.data = res.data.data || []; kategoriDesaAntiKorupsi.findMany.total = res.data.total || 0; - kategoriDesaAntiKorupsi.findMany.totalPages = res.data.totalPages || 1; + kategoriDesaAntiKorupsi.findMany.totalPages = + res.data.totalPages || 1; } else { console.error("Failed to load media sosial:", res.data?.message); kategoriDesaAntiKorupsi.findMany.data = []; @@ -363,27 +374,30 @@ const kategoriDesaAntiKorupsi = proxy({ try { kategoriDesaAntiKorupsi.delete.loading = true; - const response = await fetch( - `/api/landingpage/kategoridak/del/${id}`, - { - method: "DELETE", - headers: { - "Content-Type": "application/json", - }, - } - ); + const response = await fetch(`/api/landingpage/kategoridak/del/${id}`, { + method: "DELETE", + headers: { + "Content-Type": "application/json", + }, + }); const result = await response.json(); if (response.ok && result?.success) { - toast.success(result.message || "Kategori desa anti korupsi berhasil dihapus"); + toast.success( + result.message || "Kategori desa anti korupsi berhasil dihapus" + ); await kategoriDesaAntiKorupsi.findMany.load(); // refresh list } else { - toast.error(result?.message || "Gagal menghapus kategori desa anti korupsi"); + toast.error( + result?.message || "Gagal menghapus kategori desa anti korupsi" + ); } } catch (error) { console.error("Gagal delete:", error); - toast.error("Terjadi kesalahan saat menghapus kategori desa anti korupsi"); + toast.error( + "Terjadi kesalahan saat menghapus kategori desa anti korupsi" + ); } finally { kategoriDesaAntiKorupsi.delete.loading = false; } diff --git a/src/app/admin/(dashboard)/_state/landing-page/prestasi-desa.ts b/src/app/admin/(dashboard)/_state/landing-page/prestasi-desa.ts index 083df430..21c5e0d8 100644 --- a/src/app/admin/(dashboard)/_state/landing-page/prestasi-desa.ts +++ b/src/app/admin/(dashboard)/_state/landing-page/prestasi-desa.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import ApiFetch from "@/lib/api-fetch"; import { Prisma } from "@prisma/client"; import { toast } from "react-toastify"; @@ -62,12 +63,34 @@ const prestasiDesa = proxy({ }; }> > | null, - async load() { - const res = await ApiFetch.api.landingpage.prestasidesa[ - "find-many" - ].get(); - if (res.status === 200) { - prestasiDesa.findMany.data = res.data?.data ?? []; + page: 1, + totalPages: 1, + loading: false, + search: "", + load: async (page = 1, limit = 10, search = "") => { + prestasiDesa.findMany.loading = true; // ✅ Akses langsung via nama path + prestasiDesa.findMany.page = page; + prestasiDesa.findMany.search = search; + + try { + const query: any = { page, limit }; + if (search) query.search = search; + + const res = await ApiFetch.api.landingpage.prestasidesa["find-many"].get({ query }); + + if (res.status === 200 && res.data?.success) { + prestasiDesa.findMany.data = res.data.data ?? []; + prestasiDesa.findMany.totalPages = res.data.totalPages ?? 1; + } else { + prestasiDesa.findMany.data = []; + prestasiDesa.findMany.totalPages = 1; + } + } catch (err) { + console.error("Gagal fetch prestasi desa paginated:", err); + prestasiDesa.findMany.data = []; + prestasiDesa.findMany.totalPages = 1; + } finally { + prestasiDesa.findMany.loading = false; } }, }, @@ -283,12 +306,34 @@ const kategoriPrestasi = proxy({ id: string; name: string; }> | null, - async load() { - const res = await ApiFetch.api.landingpage.kategoriprestasi[ - "find-many" - ].get(); - if (res.status === 200) { - kategoriPrestasi.findMany.data = res.data?.data ?? []; + page: 1, + totalPages: 1, + loading: false, + search: "", + load: async (page = 1, limit = 10, search = "") => { + kategoriPrestasi.findMany.loading = true; // ✅ Akses langsung via nama path + kategoriPrestasi.findMany.page = page; + kategoriPrestasi.findMany.search = search; + + try { + const query: any = { page, limit }; + if (search) query.search = search; + + const res = await ApiFetch.api.landingpage.kategoriprestasi["find-many"].get({ query }); + + if (res.status === 200 && res.data?.success) { + kategoriPrestasi.findMany.data = res.data.data ?? []; + kategoriPrestasi.findMany.totalPages = res.data.totalPages ?? 1; + } else { + kategoriPrestasi.findMany.data = []; + kategoriPrestasi.findMany.totalPages = 1; + } + } catch (err) { + console.error("Gagal fetch kategori prestasi paginated:", err); + kategoriPrestasi.findMany.data = []; + kategoriPrestasi.findMany.totalPages = 1; + } finally { + kategoriPrestasi.findMany.loading = false; } }, }, diff --git a/src/app/admin/(dashboard)/_state/landing-page/profile.ts b/src/app/admin/(dashboard)/_state/landing-page/profile.ts index b6007bd4..f2961337 100644 --- a/src/app/admin/(dashboard)/_state/landing-page/profile.ts +++ b/src/app/admin/(dashboard)/_state/landing-page/profile.ts @@ -65,14 +65,19 @@ const programInovasi = proxy({ totalPages: 1, total: 0, loading: false, - load: async (page = 1, limit = 10) => { // Change to arrow function + search: "", + load: async (page = 1, limit = 10, search = "") => { // Change to arrow function programInovasi.findMany.loading = true; // Use the full path to access the property programInovasi.findMany.page = page; + programInovasi.findMany.search = search; try { + const query: any = { page, limit }; + if (search) query.search = search; + const res = await ApiFetch.api.landingpage.programinovasi[ "findMany" ].get({ - query: { page, limit }, + query }); if (res.status === 200 && res.data?.success) { @@ -482,14 +487,19 @@ const mediaSosial = proxy({ totalPages: 1, total: 0, loading: false, - load: async (page = 1, limit = 10) => { // Change to arrow function + search: "", + load: async (page = 1, limit = 10, search = "") => { // Change to arrow function mediaSosial.findMany.loading = true; // Use the full path to access the property mediaSosial.findMany.page = page; - try { + mediaSosial.findMany.search = search; + try { + const query: any = { page, limit }; + if (search) query.search = search; + const res = await ApiFetch.api.landingpage.mediasosial[ "findMany" ].get({ - query: { page, limit }, + query, }); if (res.status === 200 && res.data?.success) { diff --git a/src/app/admin/(dashboard)/_state/landing-page/sdgs-desa.ts b/src/app/admin/(dashboard)/_state/landing-page/sdgs-desa.ts index d6525062..50cf98dd 100644 --- a/src/app/admin/(dashboard)/_state/landing-page/sdgs-desa.ts +++ b/src/app/admin/(dashboard)/_state/landing-page/sdgs-desa.ts @@ -58,14 +58,19 @@ const sdgsDesa = proxy({ totalPages: 1, total: 0, loading: false, - load: async (page = 1, limit = 10) => { // Change to arrow function + search: "", + load: async (page = 1, limit = 10, search = "") => { // Change to arrow function sdgsDesa.findMany.loading = true; // Use the full path to access the property sdgsDesa.findMany.page = page; + sdgsDesa.findMany.search = search; try { + const query: any = { page, limit }; + if (search) query.search = search; + const res = await ApiFetch.api.landingpage.sdgsdesa[ "findMany" ].get({ - query: { page, limit }, + query, }); if (res.status === 200 && res.data?.success) { diff --git a/src/app/admin/(dashboard)/landing-page/apbdes/page.tsx b/src/app/admin/(dashboard)/landing-page/apbdes/page.tsx index ab17c080..977bd6f0 100644 --- a/src/app/admin/(dashboard)/landing-page/apbdes/page.tsx +++ b/src/app/admin/(dashboard)/landing-page/apbdes/page.tsx @@ -1,10 +1,10 @@ -/* eslint-disable react-hooks/exhaustive-deps */ 'use client' import colors from '@/con/colors'; -import { ActionIcon, Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { ActionIcon, Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { useShallowEffect } from '@mantine/hooks'; import { IconDeviceImacCog, IconFile, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; -import { useEffect, useState } from 'react'; +import { useState } from 'react'; import { useProxy } from 'valtio/utils'; import HeaderSearch from '../../_com/header'; import JudulList from '../../_com/judulList'; @@ -30,19 +30,22 @@ function APBDes() { function ListAPBDes({ search }: { search: string }) { const listState = useProxy(apbdes) const router = useRouter(); - useEffect(() => { - listState.findMany.load() - }, []) - const filteredData = (listState.findMany.data || []).filter(item => { - const keyword = search.toLowerCase(); - return ( - item.name.toLowerCase().includes(keyword) || - item.jumlah.toLowerCase().includes(keyword) - ) - }); + const { + data, + page, + totalPages, + loading, + load, + } = listState.findMany - if (!listState.findMany.data) { + useShallowEffect(() => { + load(page, 10, search) + }, [page, search]) + + const filteredData = data || [] + + if (loading || !data) { return ( @@ -88,7 +91,7 @@ function ListAPBDes({ search }: { search: string }) { rel="noopener noreferrer" variant='transparent' > - + ) : ( Tidak ada dokumen tersedia @@ -106,6 +109,14 @@ function ListAPBDes({ search }: { search: string }) { +
+ load(newPage)} + total={totalPages} + my={"md"} + /> +
) } diff --git a/src/app/admin/(dashboard)/landing-page/desa-anti-korupsi/kategori-desa-anti-korupsi/page.tsx b/src/app/admin/(dashboard)/landing-page/desa-anti-korupsi/kategori-desa-anti-korupsi/page.tsx index aa742f1e..c3d47812 100644 --- a/src/app/admin/(dashboard)/landing-page/desa-anti-korupsi/kategori-desa-anti-korupsi/page.tsx +++ b/src/app/admin/(dashboard)/landing-page/desa-anti-korupsi/kategori-desa-anti-korupsi/page.tsx @@ -1,10 +1,10 @@ -/* eslint-disable react-hooks/exhaustive-deps */ 'use client' import colors from '@/con/colors'; import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core'; +import { useShallowEffect } from '@mantine/hooks'; import { IconEdit, IconSearch, IconX } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; -import { useEffect, useMemo, useState } from 'react'; +import { useState } from 'react'; import { useProxy } from 'valtio/utils'; import HeaderSearch from '../../../_com/header'; import JudulList from '../../../_com/judulList'; @@ -50,19 +50,11 @@ function ListKategoriKegiatan({ search }: { search: string }) { } } - useEffect(() => { - load(page, 10) - }, [page]) + useShallowEffect(() => { + load(page, 10, search) + }, [page, search]) - const filteredData = useMemo(() => { - if (!data) return []; - return data.filter(item => { - const keyword = search.toLowerCase(); - return ( - item.name?.toLowerCase().includes(keyword) - ); - }) - }, [data, search]); + const filteredData = data || [] // Handle loading state if (loading || !data) { diff --git a/src/app/admin/(dashboard)/landing-page/desa-anti-korupsi/list-desa-anti-korupsi/page.tsx b/src/app/admin/(dashboard)/landing-page/desa-anti-korupsi/list-desa-anti-korupsi/page.tsx index 2ae40e67..4fad7c32 100644 --- a/src/app/admin/(dashboard)/landing-page/desa-anti-korupsi/list-desa-anti-korupsi/page.tsx +++ b/src/app/admin/(dashboard)/landing-page/desa-anti-korupsi/list-desa-anti-korupsi/page.tsx @@ -1,10 +1,10 @@ -/* eslint-disable react-hooks/exhaustive-deps */ 'use client' import colors from '@/con/colors'; import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { useShallowEffect } from '@mantine/hooks'; import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; -import { useEffect, useMemo, useState } from 'react'; +import { useState } from 'react'; import { useProxy } from 'valtio/utils'; import HeaderSearch from '../../../_com/header'; import JudulList from '../../../_com/judulList'; @@ -38,22 +38,11 @@ function ListDesaAntiKorupsi({ search }: { search: string }) { load, } = listState.findMany; - useEffect(() => { - load(page, 10); - }, [page]); + useShallowEffect(() => { + load(page, 10, search); + }, [page, search]); - const filteredData = useMemo(() => { - if (!data) return []; - return data.filter(item => { - const keyword = search.toLowerCase(); - return ( - item.name?.toLowerCase().includes(keyword) || - item.deskripsi?.toLowerCase().includes(keyword) || - item.kategori?.name?.toLowerCase().includes(keyword) - ); - }) - .sort((a, b) => b.createdAt - a.createdAt); - }, [data, search]); + const filteredData = data || [] // Handle loading state if (loading || !data) { diff --git a/src/app/admin/(dashboard)/landing-page/prestasi-desa/kategori-prestasi-desa/page.tsx b/src/app/admin/(dashboard)/landing-page/prestasi-desa/kategori-prestasi-desa/page.tsx index 20d779f7..768fd302 100644 --- a/src/app/admin/(dashboard)/landing-page/prestasi-desa/kategori-prestasi-desa/page.tsx +++ b/src/app/admin/(dashboard)/landing-page/prestasi-desa/kategori-prestasi-desa/page.tsx @@ -1,6 +1,6 @@ 'use client' import colors from '@/con/colors'; -import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core'; +import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr } from '@mantine/core'; import { useShallowEffect } from '@mantine/hooks'; import { IconEdit, IconSearch, IconX } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; @@ -42,18 +42,21 @@ function ListKategoriPrestasi({ search }: { search: string }) { } } + const { + data, + page, + totalPages, + loading, + load, + } = stateKategori.findMany + useShallowEffect(() => { - stateKategori.findMany.load() - }, []) + load(page, 10, search) + }, [page, search]) - const filteredData = (stateKategori.findMany.data || []).filter(item => { - const keyword = search.toLowerCase(); - return ( - item.name.toLowerCase().includes(keyword) - ); - }); + const filteredData = data || [] - if (!stateKategori.findMany.data) { + if (loading || !data) { return ( @@ -100,6 +103,14 @@ function ListKategoriPrestasi({ search }: { search: string }) { +
+ load(newPage)} + total={totalPages} + my={"md"} + /> +
{/* Modal Konfirmasi Hapus */} { - listState.findMany.load() - }, []) + load(page, 10, search) + }, [page, search]) - const filteredData = (listState.findMany.data || []).filter(item => { - const keyword = search.toLowerCase(); - return ( - item.name.toLowerCase().includes(keyword) || - item.deskripsi.toLowerCase().includes(keyword) || - item.kategori?.name?.toLowerCase().includes(keyword) - ); - }); + const filteredData = data || [] - if (!listState.findMany.data) { + if (loading || !data) { return ( @@ -95,6 +97,14 @@ function ListPrestasi({ search }: { search: string }) { +
+ load(newPage)} + total={totalPages} + my={"md"} + /> +
) } diff --git a/src/app/admin/(dashboard)/landing-page/profile/media-sosial/page.tsx b/src/app/admin/(dashboard)/landing-page/profile/media-sosial/page.tsx index 9a23fa29..e9d05365 100644 --- a/src/app/admin/(dashboard)/landing-page/profile/media-sosial/page.tsx +++ b/src/app/admin/(dashboard)/landing-page/profile/media-sosial/page.tsx @@ -1,10 +1,10 @@ -/* eslint-disable react-hooks/exhaustive-deps */ 'use client' import colors from '@/con/colors'; import { Box, Button, Center, Image, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { useShallowEffect } from '@mantine/hooks'; import { IconDeviceImac, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; -import { useEffect, useMemo, useState } from 'react'; +import { useState } from 'react'; import { useProxy } from 'valtio/utils'; import HeaderSearch from '../../../_com/header'; import JudulList from '../../../_com/judulList'; @@ -38,20 +38,11 @@ function ListMediaSosial({ search }: { search: string }) { load, } = stateMediaSosial.findMany; - useEffect(() => { - load(page, 10) - }, [page]) + useShallowEffect(() => { + load(page, 10, search) + }, [page, search]) - const filteredData = useMemo(() => { - if (!data) return []; - return data.filter(item => { - const keyword = search.toLowerCase(); - return ( - item.name?.toLowerCase().includes(keyword) || - item.iconUrl?.toLowerCase().includes(keyword) - ); - }) - }, [data, search]); + const filteredData = data || [] // Handle loading state if (loading || !data) { diff --git a/src/app/admin/(dashboard)/landing-page/profile/program-inovasi/page.tsx b/src/app/admin/(dashboard)/landing-page/profile/program-inovasi/page.tsx index a6af1166..b4797087 100644 --- a/src/app/admin/(dashboard)/landing-page/profile/program-inovasi/page.tsx +++ b/src/app/admin/(dashboard)/landing-page/profile/program-inovasi/page.tsx @@ -1,10 +1,10 @@ -/* eslint-disable react-hooks/exhaustive-deps */ 'use client' import colors from '@/con/colors'; import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { useShallowEffect } from '@mantine/hooks'; import { IconDeviceImac, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; -import { useEffect, useMemo, useState } from 'react'; +import { useState } from 'react'; import { useProxy } from 'valtio/utils'; import HeaderSearch from '../../../_com/header'; import JudulList from '../../../_com/judulList'; @@ -38,21 +38,11 @@ function ListProgramInovasi({ search }: { search: string }) { load, } = stateProgramInovasi.findMany; - useEffect(() => { - load(page, 10); - }, [page]); + useShallowEffect(() => { + load(page, 10, search); + }, [page, search]); - const filteredData = useMemo(() => { - if (!data) return []; - return data.filter(item => { - const keyword = search.toLowerCase(); - return ( - item.name?.toLowerCase().includes(keyword) || - item.description?.toLowerCase().includes(keyword) || - item.link?.toLowerCase().includes(keyword) - ); - }) - }, [data, search]); + const filteredData = data || [] if (loading || !data) { return ( diff --git a/src/app/admin/(dashboard)/landing-page/sdgs-desa/page.tsx b/src/app/admin/(dashboard)/landing-page/sdgs-desa/page.tsx index 25b12980..3f7d503b 100644 --- a/src/app/admin/(dashboard)/landing-page/sdgs-desa/page.tsx +++ b/src/app/admin/(dashboard)/landing-page/sdgs-desa/page.tsx @@ -1,14 +1,14 @@ -/* eslint-disable react-hooks/exhaustive-deps */ 'use client' import colors from '@/con/colors'; import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core'; +import { useShallowEffect } from '@mantine/hooks'; import { IconDeviceImacCog, IconSearch } from '@tabler/icons-react'; import { useRouter } from 'next/navigation'; -import { useEffect, useMemo, useState } from 'react'; +import { useState } from 'react'; import { useProxy } from 'valtio/utils'; import HeaderSearch from '../../_com/header'; -import sdgsDesa from '../../_state/landing-page/sdgs-desa'; import JudulList from '../../_com/judulList'; +import sdgsDesa from '../../_state/landing-page/sdgs-desa'; function SdgsDesa() { @@ -39,20 +39,11 @@ function ListSdgsDesa({ search }: { search: string }) { load, } = listState.findMany; - useEffect(() => { - load(page, 10) - }, []) + useShallowEffect(() => { + load(page, 10, search) + }, [page, search]) - const filteredData = useMemo(() => { - if (!data) return []; - return data.filter(item => { - const keyword = search.toLowerCase(); - return ( - item.name?.toLowerCase().includes(keyword) || - item.jumlah?.toLowerCase().includes(keyword) - ); - }) - }, [data, search]); + const filteredData = data || [] // Handle loading state if (loading || !data) { diff --git a/src/app/api/[[...slugs]]/_lib/landing_page/apbdes/findMany.ts b/src/app/api/[[...slugs]]/_lib/landing_page/apbdes/findMany.ts index 915dea96..b1c725d1 100644 --- a/src/app/api/[[...slugs]]/_lib/landing_page/apbdes/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/landing_page/apbdes/findMany.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ // /api/berita/findManyPaginated.ts import prisma from "@/lib/prisma"; import { Context } from "elysia"; @@ -5,12 +6,23 @@ import { Context } from "elysia"; async function apbdesFindMany(context: Context) { const page = Number(context.query.page) || 1; const limit = Number(context.query.limit) || 10; + const search = (context.query.search as string) || ''; const skip = (page - 1) * limit; + // Buat where clause + const where: any = { isActive: true }; + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { name: { contains: search, mode: 'insensitive' } }, + ]; + } + try { const [data, total] = await Promise.all([ prisma.aPBDes.findMany({ - where: { isActive: true }, + where, include: { image: true, file: true, @@ -20,7 +32,7 @@ async function apbdesFindMany(context: Context) { orderBy: { name: "asc" }, // opsional, kalau mau urut berdasarkan waktu }), prisma.aPBDes.count({ - where: { isActive: true }, + where, }), ]); diff --git a/src/app/api/[[...slugs]]/_lib/landing_page/apbdes/index.ts b/src/app/api/[[...slugs]]/_lib/landing_page/apbdes/index.ts index ad99fe99..ecfec8a7 100644 --- a/src/app/api/[[...slugs]]/_lib/landing_page/apbdes/index.ts +++ b/src/app/api/[[...slugs]]/_lib/landing_page/apbdes/index.ts @@ -11,7 +11,7 @@ const APBDes = new Elysia({ }) // ✅ Find all - .get("/find-many", apbdesFindMany) + .get("/findMany", apbdesFindMany) // ✅ Find by ID .get("/:id", apbdesFindUnique) diff --git a/src/app/api/[[...slugs]]/_lib/landing_page/desa-anti-korupsi/findMany.ts b/src/app/api/[[...slugs]]/_lib/landing_page/desa-anti-korupsi/findMany.ts index 066ed642..48284c6e 100644 --- a/src/app/api/[[...slugs]]/_lib/landing_page/desa-anti-korupsi/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/landing_page/desa-anti-korupsi/findMany.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ // /api/berita/findManyPaginated.ts import prisma from "@/lib/prisma"; import { Context } from "elysia"; @@ -5,23 +6,35 @@ import { Context } from "elysia"; async function desaAntiKorupsiFindMany(context: Context) { const page = Number(context.query.page) || 1; const limit = Number(context.query.limit) || 10; + const search = (context.query.search as string) || ""; const skip = (page - 1) * limit; + // Buat where clause + const where: any = { isActive: true }; + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { name: { contains: search, mode: "insensitive" } }, + { deskripsi: { contains: search, mode: "insensitive" } }, + { kategori: { name: { contains: search, mode: "insensitive" } } }, + ]; + } try { const [data, total] = await Promise.all([ prisma.desaAntiKorupsi.findMany({ - where: { isActive: true }, + where, include: { kategori: true, file: true, }, skip, take: limit, - orderBy: { name: 'asc' }, // opsional, kalau mau urut berdasarkan waktu + orderBy: { name: "asc" }, // opsional, kalau mau urut berdasarkan waktu }), prisma.desaAntiKorupsi.count({ - where: { isActive: true } - }) + where, + }), ]); return { diff --git a/src/app/api/[[...slugs]]/_lib/landing_page/desa-anti-korupsi/kategori-dak/findMany.ts b/src/app/api/[[...slugs]]/_lib/landing_page/desa-anti-korupsi/kategori-dak/findMany.ts index 518c40ab..aa65e321 100644 --- a/src/app/api/[[...slugs]]/_lib/landing_page/desa-anti-korupsi/kategori-dak/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/landing_page/desa-anti-korupsi/kategori-dak/findMany.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ // /api/berita/findManyPaginated.ts import prisma from "@/lib/prisma"; import { Context } from "elysia"; @@ -5,18 +6,29 @@ import { Context } from "elysia"; async function kategoriDesaAntiKorupsiFindMany(context: Context) { const page = Number(context.query.page) || 1; const limit = Number(context.query.limit) || 10; + const search = (context.query.search as string) || ''; const skip = (page - 1) * limit; + // Buat where clause + const where: any = { isActive: true }; + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { name: { contains: search, mode: 'insensitive' } }, + ]; + } + try { const [data, total] = await Promise.all([ prisma.kategoriDesaAntiKorupsi.findMany({ - where: { isActive: true }, + where, skip, take: limit, orderBy: { name: 'asc' }, // opsional, kalau mau urut berdasarkan waktu }), prisma.kategoriDesaAntiKorupsi.count({ - where: { isActive: true } + where, }) ]); diff --git a/src/app/api/[[...slugs]]/_lib/landing_page/prestasi-desa/findMany.ts b/src/app/api/[[...slugs]]/_lib/landing_page/prestasi-desa/findMany.ts index d2a02a31..fa22a5a6 100644 --- a/src/app/api/[[...slugs]]/_lib/landing_page/prestasi-desa/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/landing_page/prestasi-desa/findMany.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ // /api/berita/findManyPaginated.ts import prisma from "@/lib/prisma"; import { Context } from "elysia"; @@ -5,12 +6,25 @@ import { Context } from "elysia"; async function prestasiDesaFindMany(context: Context) { const page = Number(context.query.page) || 1; const limit = Number(context.query.limit) || 10; + const search = (context.query.search as string) || ''; const skip = (page - 1) * limit; + // Buat where clause + const where: any = { isActive: true }; + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { name: { contains: search, mode: 'insensitive' } }, + { deskripsi: { contains: search, mode: 'insensitive' } }, + { kategori: { name: { contains: search, mode: 'insensitive' } } }, + ]; + } + try { const [data, total] = await Promise.all([ prisma.prestasiDesa.findMany({ - where: { isActive: true }, + where, include: { image: true, kategori: true, @@ -20,7 +34,7 @@ async function prestasiDesaFindMany(context: Context) { orderBy: { createdAt: "desc" }, // opsional, kalau mau urut berdasarkan waktu }), prisma.prestasiDesa.count({ - where: { isActive: true }, + where, }), ]); diff --git a/src/app/api/[[...slugs]]/_lib/landing_page/prestasi-desa/kategori-prestasi/findMany.ts b/src/app/api/[[...slugs]]/_lib/landing_page/prestasi-desa/kategori-prestasi/findMany.ts index f0d900e7..7f49568b 100644 --- a/src/app/api/[[...slugs]]/_lib/landing_page/prestasi-desa/kategori-prestasi/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/landing_page/prestasi-desa/kategori-prestasi/findMany.ts @@ -1,15 +1,52 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ +// /api/berita/findManyPaginated.ts import prisma from "@/lib/prisma"; +import { Context } from "elysia"; -export default async function kategoriPrestasiFindMany() { - const data = await prisma.kategoriPrestasiDesa.findMany(); - return { - success: true, - data: data.map((item: any) => { - return { - id: item.id, - name: item.name, - } - }), +async function kategoriPrestasiFindMany(context: Context) { + const page = Number(context.query.page) || 1; + const limit = Number(context.query.limit) || 10; + const search = (context.query.search as string) || ''; + const skip = (page - 1) * limit; + + // Buat where clause + const where: any = { isActive: true }; + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { name: { contains: search, mode: 'insensitive' } }, + ]; + } + + try { + const [data, total] = await Promise.all([ + prisma.kategoriPrestasiDesa.findMany({ + where, + skip, + take: limit, + orderBy: { createdAt: "desc" }, // opsional, kalau mau urut berdasarkan waktu + }), + prisma.kategoriPrestasiDesa.count({ + where, + }), + ]); + + return { + success: true, + message: "Success fetch Kategori Prestasi Desa with pagination", + data, + page, + totalPages: Math.ceil(total / limit), + total, }; -} \ No newline at end of file + } catch (e) { + console.error("Find many paginated error:", e); + return { + success: false, + message: "Failed fetch Kategori Prestasi Desa with pagination", + }; + } +} + +export default kategoriPrestasiFindMany; diff --git a/src/app/api/[[...slugs]]/_lib/landing_page/profile/media-sosial/findMany.ts b/src/app/api/[[...slugs]]/_lib/landing_page/profile/media-sosial/findMany.ts index 63707e17..82bfe153 100644 --- a/src/app/api/[[...slugs]]/_lib/landing_page/profile/media-sosial/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/landing_page/profile/media-sosial/findMany.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ // /api/berita/findManyPaginated.ts import prisma from "@/lib/prisma"; import { Context } from "elysia"; @@ -5,12 +6,23 @@ import { Context } from "elysia"; async function mediaSosialFindMany(context: Context) { const page = Number(context.query.page) || 1; const limit = Number(context.query.limit) || 10; + const search = (context.query.search as string) || ''; const skip = (page - 1) * limit; + // Buat where clause + const where: any = { isActive: true }; + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { name: { contains: search, mode: 'insensitive' } }, + ]; + } + try { const [data, total] = await Promise.all([ prisma.mediaSosial.findMany({ - where: { isActive: true }, + where, include: { image: true, }, diff --git a/src/app/api/[[...slugs]]/_lib/landing_page/profile/program-inovasi/findMany.ts b/src/app/api/[[...slugs]]/_lib/landing_page/profile/program-inovasi/findMany.ts index 7fdfda9b..583abcb1 100644 --- a/src/app/api/[[...slugs]]/_lib/landing_page/profile/program-inovasi/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/landing_page/profile/program-inovasi/findMany.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ // // /api/berita/findManyPaginated.ts import prisma from "@/lib/prisma"; import { Context } from "elysia"; @@ -5,12 +6,23 @@ import { Context } from "elysia"; async function programInovasiFindMany(context: Context) { const page = Number(context.query.page) || 1; const limit = Number(context.query.limit) || 10; + const search = (context.query.search as string) || ''; const skip = (page - 1) * limit; + const where: any = { isActive: true }; + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { name: { contains: search, mode: 'insensitive' } }, + { description: { contains: search, mode: 'insensitive' } }, + ]; + } + try { const [data, total] = await Promise.all([ prisma.programInovasi.findMany({ - where: { isActive: true }, + where, include: { image: true, }, diff --git a/src/app/api/[[...slugs]]/_lib/landing_page/sdgs-desa/findMany.ts b/src/app/api/[[...slugs]]/_lib/landing_page/sdgs-desa/findMany.ts index 318e2cf2..a41e1da5 100644 --- a/src/app/api/[[...slugs]]/_lib/landing_page/sdgs-desa/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/landing_page/sdgs-desa/findMany.ts @@ -1,3 +1,4 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ // /api/berita/findManyPaginated.ts import prisma from "@/lib/prisma"; import { Context } from "elysia"; @@ -5,12 +6,23 @@ import { Context } from "elysia"; async function sdgsDesaFindMany(context: Context) { const page = Number(context.query.page) || 1; const limit = Number(context.query.limit) || 10; + const search = (context.query.search as string) || ''; const skip = (page - 1) * limit; + // Buat where clause + const where: any = { isActive: true }; + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { name: { contains: search, mode: 'insensitive' } }, + ]; + } + try { const [data, total] = await Promise.all([ prisma.sDGSDesa.findMany({ - where: { isActive: true }, + where, include: { image: true, }, @@ -19,7 +31,7 @@ async function sdgsDesaFindMany(context: Context) { orderBy: { jumlah: "desc" }, // opsional, kalau mau urut berdasarkan waktu }), prisma.sDGSDesa.count({ - where: { isActive: true }, + where, }), ]);