From 760ba4b6d21e167ad1905bc47df8db746798faab Mon Sep 17 00:00:00 2001 From: nico Date: Fri, 22 Aug 2025 00:26:58 +0800 Subject: [PATCH] Sinkronisasi Sinkronisasi UI & API Admin - User Submenu Program Kemiskinan --- .../_state/ekonomi/program-kemiskinan.ts | 43 ++++-- .../ekonomi/program-kemiskinan/page.tsx | 41 +++-- .../ekonomi/program-kemiskinan/findMany.ts | 65 ++++++-- .../ekonomi/jumlah-pengangguran/page.tsx | 8 - .../ekonomi/program-kemiskinan/page.tsx | 146 +++++++++++------- 5 files changed, 195 insertions(+), 108 deletions(-) diff --git a/src/app/admin/(dashboard)/_state/ekonomi/program-kemiskinan.ts b/src/app/admin/(dashboard)/_state/ekonomi/program-kemiskinan.ts index 24b97801..0da2a711 100644 --- a/src/app/admin/(dashboard)/_state/ekonomi/program-kemiskinan.ts +++ b/src/app/admin/(dashboard)/_state/ekonomi/program-kemiskinan.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"; @@ -11,8 +12,7 @@ const templateForm = z.object({ statistik: z.object({ tahun: z.string().min(1, "Tahun minimal 1 karakter"), jumlah: z.string().min(1, "Jumlah minimal 1 karakter"), - }) - + }), }); const defaultForm = { @@ -21,8 +21,8 @@ const defaultForm = { ikonUrl: "", statistik: { tahun: "", - jumlah: "" - } + jumlah: "", + }, }; const programKemiskinanState = proxy({ @@ -64,12 +64,35 @@ const programKemiskinanState = proxy({ }; }>[], loading: false, - async load() { - const res = await ApiFetch.api.ekonomi.programkemiskinan[ - "find-many" - ].get(); - if (res.status === 200) { - programKemiskinanState.findMany.data = res.data?.data ?? []; + page: 1, + totalPages: 1, + search: "", + load: async (page = 1, limit = 10, search = "") => { + programKemiskinanState.findMany.loading = true; // ✅ Akses langsung via nama path + programKemiskinanState.findMany.page = page; + programKemiskinanState.findMany.search = search; + + try { + const query: any = { page, limit }; + if (search) query.search = search; + + const res = await ApiFetch.api.ekonomi.programkemiskinan[ + "find-many" + ].get({ query }); + + if (res.status === 200 && res.data?.success) { + programKemiskinanState.findMany.data = res.data.data ?? []; + programKemiskinanState.findMany.totalPages = res.data.totalPages ?? 1; + } else { + programKemiskinanState.findMany.data = []; + programKemiskinanState.findMany.totalPages = 1; + } + } catch (err) { + console.error("Gagal fetch program kemiskinan paginated:", err); + programKemiskinanState.findMany.data = []; + programKemiskinanState.findMany.totalPages = 1; + } finally { + programKemiskinanState.findMany.loading = false; } }, }, diff --git a/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/page.tsx b/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/page.tsx index 951f3254..3dfa48d2 100644 --- a/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/page.tsx +++ b/src/app/admin/(dashboard)/ekonomi/program-kemiskinan/page.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ 'use client' import colors from '@/con/colors'; -import { Box, Button, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; +import { Box, Button, Center, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; import { IconDeviceImac, IconSearch } from '@tabler/icons-react'; import HeaderSearch from '../../_com/header'; import JudulList from '../../_com/judulList'; @@ -23,7 +23,7 @@ function ProgramKemiskinan() { value={search} onChange={(e) => setSearch(e.currentTarget.value)} /> - + ); } @@ -34,14 +34,22 @@ function ListProgramKemiskinan({ search }: { search: string }) { const [lineChart, setLineChart] = useState([]); const [mounted, setMounted] = useState(false); + const { + data, + page, + totalPages, + loading, + load, + } = programState.findMany; + useShallowEffect(() => { setMounted(true) - programState.findMany.load() + load(page, 10, search) }, []) useEffect(() => { - if (programState.findMany.data) { - const chartData = programState.findMany.data + if (data) { + const chartData = data .filter(item => item.statistik) .map(item => ({ tahun: item.statistik?.tahun, @@ -52,18 +60,11 @@ function ListProgramKemiskinan({ search }: { search: string }) { setLineChart(chartData); } - }, [programState.findMany.data]) + }, [data]) - const filteredData = (programState.findMany.data || []).filter(item => { - const keyword = search.toLowerCase(); - return ( - item.nama.toLowerCase().includes(keyword) || - item.deskripsi.toLowerCase().includes(keyword) || - item.statistik?.tahun.toString().includes(keyword) - ); - }); + const filteredData = data || [] - if (!programState.findMany.data) { + if (loading || !data) { return ( @@ -112,7 +113,7 @@ function ListProgramKemiskinan({ search }: { search: string }) { Grafik Berdasarkan Responden {mounted && lineChart.length > 0 ? ( - + +
+ load(newPage)} + total={totalPages} + my={"md"} + /> +
); diff --git a/src/app/api/[[...slugs]]/_lib/ekonomi/program-kemiskinan/findMany.ts b/src/app/api/[[...slugs]]/_lib/ekonomi/program-kemiskinan/findMany.ts index f1d1f597..01ea8957 100644 --- a/src/app/api/[[...slugs]]/_lib/ekonomi/program-kemiskinan/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/ekonomi/program-kemiskinan/findMany.ts @@ -1,18 +1,53 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import prisma from "@/lib/prisma"; +import { Context } from "elysia"; -export default async function programKemiskinanFindMany() { - const data = await prisma.programKemiskinan.findMany({ - include: { - statistik: true, // ikut sertakan relasinya - }, - orderBy: { - createdAt: "desc", - }, - }); - - return { - success: true, - message: "Success get all program layanan", - data, - }; +export default async function programKemiskinanFindMany(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 = [ + { nama: { contains: search, mode: 'insensitive' } }, + { deskripsi: { contains: search, mode: 'insensitive' } }, + ]; + } + + try { + // Ambil data dan total count secara paralel + const [data, total] = await Promise.all([ + prisma.programKemiskinan.findMany({ + where, + include: { + statistik: true, + }, + skip, + take: limit, + orderBy: { createdAt: 'desc' }, + }), + prisma.programKemiskinan.count({ where }), + ]); + + return { + success: true, + message: "Berhasil ambil program kemiskinan dengan pagination", + data, + page, + limit, + total, + totalPages: Math.ceil(total / limit), + }; + } catch (e) { + console.error("Error di findMany paginated:", e); + return { + success: false, + message: "Gagal mengambil data program kemiskinan", + }; + } } diff --git a/src/app/darmasaba/(pages)/ekonomi/jumlah-pengangguran/page.tsx b/src/app/darmasaba/(pages)/ekonomi/jumlah-pengangguran/page.tsx index b5a3d99d..0bafd301 100644 --- a/src/app/darmasaba/(pages)/ekonomi/jumlah-pengangguran/page.tsx +++ b/src/app/darmasaba/(pages)/ekonomi/jumlah-pengangguran/page.tsx @@ -50,14 +50,6 @@ function Page() { DATA PENGANGGURAN DESA - {/* -