From b6d6583e77c318f0792a6881b80e36795040c39b Mon Sep 17 00:00:00 2001 From: nico Date: Fri, 29 Aug 2025 01:31:05 +0800 Subject: [PATCH] Sinkroniasasi Admin - User, Submenu Info Sekolah Paud --- .../_state/pendidikan/info-sekolah-paud.ts | 68 ++-- .../info-sekolah-paud/lembaga/findMany.ts | 76 +++- .../info-sekolah-paud/pengajar/findMany.ts | 88 +++-- .../info-sekolah-paud/siswa/findMany.ts | 85 ++-- .../(pages)/desa/berita/semua/page.tsx | 70 ++-- .../[jenjangPendidikan]/content.tsx | 260 +++++++++++++ .../[jenjangPendidikan]/lembaga/page.tsx | 109 ++++++ .../[jenjangPendidikan]/page.tsx | 14 + .../[jenjangPendidikan]/pengajar/page.tsx | 111 ++++++ .../[jenjangPendidikan]/siswa/page.tsx | 111 ++++++ .../info-sekolah-paud/_lib/layoutTabs.tsx | 127 ++++++ .../pendidikan/info-sekolah-paud/layout.tsx | 18 + .../pendidikan/info-sekolah-paud/page.tsx | 363 ------------------ .../info-sekolah-paud/semua/lembaga/page.tsx | 100 +++++ .../info-sekolah-paud/semua/page.tsx | 271 +++++++++++++ .../info-sekolah-paud/semua/pengajar/page.tsx | 102 +++++ .../info-sekolah-paud/semua/siswa/page.tsx | 102 +++++ src/con/navbar-list-menu.ts | 2 +- 18 files changed, 1592 insertions(+), 485 deletions(-) create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/content.tsx create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/lembaga/page.tsx create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/page.tsx create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/pengajar/page.tsx create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/siswa/page.tsx create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/_lib/layoutTabs.tsx create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/layout.tsx delete mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/page.tsx create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/lembaga/page.tsx create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/page.tsx create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/pengajar/page.tsx create mode 100644 src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/siswa/page.tsx diff --git a/src/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud.ts b/src/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud.ts index a96f7b1f..d8821362 100644 --- a/src/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud.ts +++ b/src/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud.ts @@ -343,33 +343,40 @@ const lembagaPendidikan = proxy({ total: 0, loading: false, search: "", - load: async (page = 1, limit = 10, search = "") => { - // Change to arrow function - lembagaPendidikan.findMany.loading = true; // Use the full path to access the property + load: async (page = 1, limit = 10, search = "", jenjangPendidikan = "") => { + lembagaPendidikan.findMany.loading = true; lembagaPendidikan.findMany.page = page; lembagaPendidikan.findMany.search = search; + try { - const query: any = { page, limit }; - if (search) query.search = search; - const res = - await ApiFetch.api.pendidikan.infosekolahpaud.lembagapendidikan[ - "find-many" - ].get({ - query, - }); + const query: any = { + page, + limit, + ...(search && { search }), + ...(jenjangPendidikan && { jenjangPendidikanId: jenjangPendidikan }) + }; + + console.log('Fetching lembaga with query:', query); + + const res = await ApiFetch.api.pendidikan.infosekolahpaud.lembagapendidikan["find-many"].get({ query }); + + console.log('API Response:', res); if (res.status === 200 && res.data?.success) { - lembagaPendidikan.findMany.data = res.data.data || []; - lembagaPendidikan.findMany.total = res.data.total || 0; - lembagaPendidikan.findMany.totalPages = res.data.totalPages || 1; + lembagaPendidikan.findMany.data = Array.isArray(res.data.data) ? res.data.data : []; + lembagaPendidikan.findMany.total = typeof res.data.total === 'number' ? res.data.total : 0; + lembagaPendidikan.findMany.totalPages = typeof res.data.totalPages === 'number' ? res.data.totalPages : 1; + console.log('Successfully loaded lembaga data:', { + count: lembagaPendidikan.findMany.data.length, + total: lembagaPendidikan.findMany.total, + totalPages: lembagaPendidikan.findMany.totalPages + }); } else { console.error( "Failed to load lembaga pendidikan:", - res.data?.message + res.data?.message || 'No error message provided' ); - lembagaPendidikan.findMany.data = []; - lembagaPendidikan.findMany.total = 0; - lembagaPendidikan.findMany.totalPages = 1; + throw new Error(res.data?.message || 'Failed to load lembaga pendidikan'); } } catch (error) { console.error("Error loading lembaga pendidikan:", error); @@ -621,7 +628,11 @@ const siswa = proxy({ data: null as Array< Prisma.SiswaGetPayload<{ include: { - lembaga: true; + lembaga: { + include: { + jenjangPendidikan: true; + }; + }; }; }> > | null, @@ -630,14 +641,16 @@ const siswa = proxy({ total: 0, loading: false, search: "", - load: async (page = 1, limit = 10, search = "") => { - // Change to arrow function - siswa.findMany.loading = true; // Use the full path to access the property + jenjangPendidikan: "", + load: async (page = 1, limit = 10, search = "", jenjangPendidikan = "") => { + siswa.findMany.loading = true; siswa.findMany.page = page; siswa.findMany.search = search; + siswa.findMany.jenjangPendidikan = jenjangPendidikan; try { const query: any = { page, limit }; if (search) query.search = search; + if (jenjangPendidikan) query.jenjangPendidikanName = jenjangPendidikan; const res = await ApiFetch.api.pendidikan.infosekolahpaud.siswa[ "find-many" ].get({ @@ -894,7 +907,11 @@ const pengajar = proxy({ data: null as Array< Prisma.PengajarGetPayload<{ include: { - lembaga: true; + lembaga: { + include: { + jenjangPendidikan: true + } + } }; }> > | null, @@ -903,14 +920,17 @@ const pengajar = proxy({ total: 0, loading: false, search: "", - load: async (page = 1, limit = 10, search = "") => { + jenjangPendidikan: "", + load: async (page = 1, limit = 10, search = "", jenjangPendidikan = "") => { // Change to arrow function pengajar.findMany.loading = true; // Use the full path to access the property pengajar.findMany.page = page; pengajar.findMany.search = search; + pengajar.findMany.jenjangPendidikan = jenjangPendidikan; try { const query: any = { page, limit }; if (search) query.search = search; + if (jenjangPendidikan) query.jenjangPendidikanId = jenjangPendidikan; const res = await ApiFetch.api.pendidikan.infosekolahpaud.pengajar[ "find-many" ].get({ diff --git a/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/lembaga/findMany.ts b/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/lembaga/findMany.ts index 78f63089..73af2af7 100644 --- a/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/lembaga/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/lembaga/findMany.ts @@ -4,25 +4,58 @@ import prisma from "@/lib/prisma"; import { Context } from "elysia"; async function lembagaPendidikanFindMany(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" } }, - { siswa: { contains: search, mode: "insensitive" } }, - { pengajar: { contains: search, mode: "insensitive" } }, - { jenjangPendidikan: { contains: search, mode: "insensitive" } }, - ]; - } - try { + 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 jenjangPendidikanName = (context.query.jenjangPendidikanId as string) || ""; + + console.log('Lembaga API Query Params:', { page, limit, search, jenjangPendidikanName }); + + // Buat where clause + const where: any = { isActive: true }; + + // Filter berdasarkan jenjang pendidikan (jika ada) + if (jenjangPendidikanName) { + // Cari jenjang pendidikan berdasarkan nama + const jenjangPendidikan = await prisma.jenjangPendidikan.findFirst({ + where: { + nama: { + equals: jenjangPendidikanName, + mode: 'insensitive', + }, + isActive: true, + }, + orderBy: { nama: 'desc' }, + }); + + if (jenjangPendidikan) { + where.jenjangId = jenjangPendidikan.id; + } else { + // Jika tidak ditemukan, return data kosong + return { + success: true, + message: "Jenjang pendidikan tidak ditemukan", + data: [], + page, + limit, + totalPages: 0, + total: 0, + }; + } + } + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { nama: { contains: search, mode: "insensitive" } }, + { siswa: { nama: { contains: search, mode: "insensitive" } } }, + { pengajar: { nama: { contains: search, mode: "insensitive" } } }, + { jenjangPendidikan: { nama: { contains: search, mode: "insensitive" } } }, + ]; + } + const [data, total] = await Promise.all([ prisma.lembaga.findMany({ where, @@ -33,13 +66,16 @@ async function lembagaPendidikanFindMany(context: Context) { }, skip, take: limit, - orderBy: { createdAt: 'desc' }, // opsional, kalau mau urut berdasarkan waktu + orderBy: { jenjangPendidikan: { nama: 'asc' } }, }), prisma.lembaga.count({ where, }) ]); + console.log('Fetched data count:', data.length); + console.log('Total count:', total); + return { success: true, message: "Success fetch lembaga pendidikan with pagination", @@ -53,7 +89,7 @@ async function lembagaPendidikanFindMany(context: Context) { console.error("Find many paginated error:", e); return { success: false, - message: "Failed fetch lembaga pendidikan with pagination", + message: `Failed fetch lembaga pendidikan: ${e instanceof Error ? e.message : 'Unknown error'}`, }; } } diff --git a/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/pengajar/findMany.ts b/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/pengajar/findMany.ts index d5232b7c..df81c59f 100644 --- a/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/pengajar/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/pengajar/findMany.ts @@ -1,41 +1,82 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -// /api/berita/findManyPaginated.ts import prisma from "@/lib/prisma"; import { Context } from "elysia"; async function pengajarFindMany(context: Context) { - const page = Number(context.query.page) || 1; - const limit = Number(context.query.limit) || 10; - const skip = (page - 1) * limit; - const search = (context.query.search as string) || ""; - - // Buat where clause - const where: any = { isActive: true }; - - // Tambahkan pencarian (jika ada) - if (search) { - where.OR = [ - { nama: { contains: search, mode: "insensitive" } }, - { lembaga: { contains: search, mode: "insensitive" } }, - ]; - } - try { + const page = Number(context.query.page) || 1; + const limit = Number(context.query.limit) || 10; + const skip = (page - 1) * limit; + const search = (context.query.search as string) || ""; + const jenjangPendidikanName = (context.query.jenjangPendidikanId as string) || ""; + + console.log('Pengajar API Query Params:', { page, limit, search, jenjangPendidikanId: jenjangPendidikanName }); + + const where: any = { isActive: true }; + + // Filter berdasarkan jenjang pendidikan (jika ada) + if (jenjangPendidikanName) { + // Cari jenjang pendidikan berdasarkan nama + const jenjangPendidikan = await prisma.jenjangPendidikan.findFirst({ + where: { + nama: { + equals: jenjangPendidikanName, + mode: 'insensitive' + }, + isActive: true + }, + orderBy: { nama: 'desc' }, + }); + + if (jenjangPendidikan) { + where.lembaga = { + ...where.lembaga, + jenjangId: jenjangPendidikan.id + }; + } else { + // Jika tidak ditemukan, return data kosong + return { + success: true, + message: "Jenjang pendidikan tidak ditemukan", + data: [], + page, + limit, + totalPages: 0, + total: 0, + }; + } + } + + // Add search condition if search term exists + if (search) { + where.OR = [ + { nama: { contains: search, mode: 'insensitive' } }, + { lembaga: { nama: { contains: search, mode: 'insensitive' } } } + ]; + } + const [data, total] = await Promise.all([ prisma.pengajar.findMany({ where, include: { - lembaga: true, + lembaga: { + include: { + jenjangPendidikan: true + } + } }, skip, take: limit, - orderBy: { createdAt: 'desc' }, // opsional, kalau mau urut berdasarkan waktu + orderBy: { lembaga: { jenjangPendidikan: { nama: 'asc' } } }, }), prisma.pengajar.count({ where, }) ]); + console.log('Fetched pengajar data count:', data.length); + console.log('Total pengajar count:', total); + return { success: true, message: "Success fetch pengajar with pagination", @@ -45,13 +86,12 @@ async function pengajarFindMany(context: Context) { totalPages: Math.ceil(total / limit), total, }; - } catch (e) { - console.error("Find many paginated error:", e); + } catch (error) { + console.error("Error in pengajarFindMany:", error); return { success: false, - message: "Failed fetch pengajar with pagination", + message: `Failed fetch pengajar: ${error instanceof Error ? error.message : 'Unknown error'}`, }; } } - -export default pengajarFindMany; +export default pengajarFindMany; \ No newline at end of file diff --git a/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/siswa/findMany.ts b/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/siswa/findMany.ts index 590fdcaf..654e8526 100644 --- a/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/siswa/findMany.ts +++ b/src/app/api/[[...slugs]]/_lib/pendidikan/info-sekolah-paud/siswa/findMany.ts @@ -1,41 +1,82 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ -// /api/berita/findManyPaginated.ts import prisma from "@/lib/prisma"; import { Context } from "elysia"; async function siswaFindMany(context: Context) { - const page = Number(context.query.page) || 1; - const limit = Number(context.query.limit) || 10; - const skip = (page - 1) * limit; - const search = (context.query.search as string) || ""; - - // Buat where clause - const where: any = { isActive: true }; - - // Tambahkan pencarian (jika ada) - if (search) { - where.OR = [ - { nama: { contains: search, mode: "insensitive" } }, - { lembaga: { contains: search, mode: "insensitive" } }, - ]; - } - try { + const page = Number(context.query.page) || 1; + const limit = Number(context.query.limit) || 10; + const skip = (page - 1) * limit; + const search = (context.query.search as string) || ""; + const jenjangPendidikanName = (context.query.jenjangPendidikanName as string) || ""; + + console.log('Siswa API Query Params:', { page, limit, search, jenjangPendidikanId: jenjangPendidikanName }); + + // Buat where clause + const where: any = { isActive: true }; + + // Filter berdasarkan jenjang pendidikan (jika ada) + if (jenjangPendidikanName) { + // Cari jenjang pendidikan berdasarkan nama + const jenjangPendidikan = await prisma.jenjangPendidikan.findFirst({ + where: { + nama: { + equals: jenjangPendidikanName, + mode: 'insensitive' + }, + isActive: true, + } + }); + + if (jenjangPendidikan) { + where.lembaga = { + ...where.lembaga, + jenjangId: jenjangPendidikan.id + }; + } else { + // Jika tidak ditemukan, return data kosong + return { + success: true, + message: "Jenjang pendidikan tidak ditemukan", + data: [], + page, + limit, + totalPages: 0, + total: 0, + }; + } + } + + // Tambahkan pencarian (jika ada) + if (search) { + where.OR = [ + { nama: { contains: search, mode: "insensitive" } }, + { lembaga: { nama: { contains: search, mode: 'insensitive' } } } + ]; + } + const [data, total] = await Promise.all([ prisma.siswa.findMany({ where, include: { - lembaga: true, + lembaga: { + include: { + jenjangPendidikan: true, + }, + }, }, skip, take: limit, - orderBy: { createdAt: 'desc' }, // opsional, kalau mau urut berdasarkan waktu + orderBy: { lembaga: { jenjangPendidikan: { nama: 'asc' } } }, }), prisma.siswa.count({ where, }) ]); + console.log('Fetched siswa data count:', data.length); + console.log('Total siswa count:', total); + return { success: true, message: "Success fetch siswa with pagination", @@ -45,11 +86,11 @@ async function siswaFindMany(context: Context) { totalPages: Math.ceil(total / limit), total, }; - } catch (e) { - console.error("Find many paginated error:", e); + } catch (error) { + console.error("Error in siswaFindMany:", error); return { success: false, - message: "Failed fetch siswa with pagination", + message: `Failed fetch siswa: ${error instanceof Error ? error.message : 'Unknown error'}`, }; } } diff --git a/src/app/darmasaba/(pages)/desa/berita/semua/page.tsx b/src/app/darmasaba/(pages)/desa/berita/semua/page.tsx index 37558539..8c8568da 100644 --- a/src/app/darmasaba/(pages)/desa/berita/semua/page.tsx +++ b/src/app/darmasaba/(pages)/desa/berita/semua/page.tsx @@ -1,48 +1,53 @@ /* eslint-disable react-hooks/exhaustive-deps */ 'use client' import stateDashboardBerita from '@/app/admin/(dashboard)/_state/desa/berita'; -import { Badge, Box, Button, Card, Center, Container, Divider, Flex, Grid, GridCol, Group, Image, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, Title } from '@mantine/core'; +import { + Badge, Box, Button, Card, Center, Container, Divider, + Flex, Grid, GridCol, Group, Image, Pagination, + Paper, SimpleGrid, Skeleton, Stack, Text, Title +} from '@mantine/core'; import { IconArrowRight, IconCalendar } from '@tabler/icons-react'; import { useTransitionRouter } from 'next-view-transitions'; import { useSearchParams } from 'next/navigation'; -import { useEffect, useState } from 'react'; +import { useEffect } from 'react'; import { useProxy } from 'valtio/utils'; function Semua() { const searchParams = useSearchParams(); const router = useTransitionRouter(); - // Parameter URL + // Ambil parameter langsung dari URL const search = searchParams.get('search') || ''; - const currentPage = parseInt(searchParams.get('page') || '1'); - const [page, setPage] = useState(currentPage); + const page = parseInt(searchParams.get('page') || '1'); - // Gunakan proxy untuk state + // Gunakan proxy untuk state global const state = useProxy(stateDashboardBerita.berita); - const featured = useProxy(stateDashboardBerita.berita.findFirst); // ✅ Berita utama + const featured = useProxy(stateDashboardBerita.berita.findFirst); const loadingGrid = state.findMany.loading; const loadingFeatured = featured.loading; - // Load berita utama (hanya sekali) + // Load berita utama sekali saja useEffect(() => { if (!featured.data && !loadingFeatured) { stateDashboardBerita.berita.findFirst.load(); } }, [featured.data, loadingFeatured]); - // Load berita terbaru (untuk grid) saat page/search berubah + // Load berita terbaru tiap page / search berubah useEffect(() => { - const limit = 3; // Sesuaikan dengan tampilan grid + const limit = 3; state.findMany.load(page, limit, search); }, [page, search]); - // Update URL saat page berubah - useEffect(() => { - const url = new URLSearchParams(); + // Handler pagination → langsung update URL + const handlePageChange = (newPage: number) => { + const url = new URLSearchParams(searchParams.toString()); if (search) url.set('search', search); - if (page > 1) url.set('page', page.toString()); + if (newPage > 1) url.set('page', newPage.toString()); + else url.delete('page'); // biar page=1 ga muncul di URL + router.replace(`?${url.toString()}`); - }, [search, page, router]); + }; const featuredData = featured.data; const paginatedNews = state.findMany.data || []; @@ -51,7 +56,7 @@ function Semua() { return ( - {/* === Berita Utama (Tetap) === */} + {/* === Berita Utama === */} {loadingFeatured ? (
) : featuredData ? ( @@ -94,7 +99,9 @@ function Semua() { @@ -106,7 +113,7 @@ function Semua() {
) : null} - {/* === Berita Terbaru (Berubah Saat Pagination) === */} + {/* === Berita Terbaru === */} Berita Terbaru @@ -122,13 +129,7 @@ function Semua() { ) : ( {paginatedNews.map((item) => ( - + {item.judul} - {item.deskripsi} @@ -154,20 +154,28 @@ function Semua() { year: 'numeric' })} - - + ))} )} - {/* Pagination hanya untuk berita terbaru */} + {/* Pagination */}
; + jumlah: number; + nama: string; + helper?: string; + loading?: boolean; +} + +export default function KategoriPage({ jenjangPendidikan }: { jenjangPendidikan: string }) { + const router = useTransitionRouter(); + const [stats, setStats] = useState([]); + const [isLoading, setIsLoading] = useState(true); + + // Decode the URL parameter + const decodedJenjangPendidikan = decodeURIComponent(jenjangPendidikan); + const jenjangFilter = decodedJenjangPendidikan.toLowerCase() === 'semua' + ? undefined + : decodedJenjangPendidikan; + + const loadData = useCallback(async () => { + if (!decodedJenjangPendidikan) return; + + try { + setIsLoading(true); + + // Load all data in parallel with the jenjang filter + await Promise.all([ + infoSekolahPaud.lembagaPendidikan.findMany.load(1, 100, '', jenjangFilter), + infoSekolahPaud.siswa.findMany.load(1, 100, '', jenjangFilter), + infoSekolahPaud.pengajar.findMany.load(1, 100, '', jenjangFilter), + ]); + + // Get filtered totals based on jenjang + const totalLembaga = infoSekolahPaud.lembagaPendidikan.findMany.total || 0; + const totalSiswa = infoSekolahPaud.siswa.findMany.total || 0; + const totalPengajar = infoSekolahPaud.pengajar.findMany.total || 0; + + setStats([ + { + + icon: IconChalkboard, + jumlah: totalLembaga, + nama: 'Lembaga Pendidikan', + helper: 'Jumlah institusi pendidikan resmi di wilayah ini', + loading: false, + jenjangPendidikan: decodedJenjangPendidikan, + }, + { + icon: IconSchool, + jumlah: totalSiswa, + nama: 'Siswa Terdaftar', + helper: 'Total siswa aktif di semua jenjang', + loading: false, + jenjangPendidikan: decodedJenjangPendidikan, + }, + { + icon: IconMicroscope, + jumlah: totalPengajar, + nama: 'Tenaga Pengajar', + helper: 'Jumlah guru dan staf pengajar aktif', + loading: false, + jenjangPendidikan: decodedJenjangPendidikan, + }, + ]); + } catch (error) { + console.error('Error loading data:', error); + // Set error state or show toast notification + } finally { + setIsLoading(false); + } + }, [decodedJenjangPendidikan, jenjangFilter]); + + useEffect(() => { + loadData(); + }, [loadData, decodedJenjangPendidikan]); + + const handleRefresh = () => { + loadData(); + }; + + const hasilCount = stats.reduce((sum, stat) => sum + stat.jumlah, 0); + const filtered = stats; + + if (isLoading) { + return ( + + + + {[1, 2, 3].map((i) => ( + + ))} + + + + ); + } + + return ( + + + + + + + Menampilkan {hasilCount} hasil. + + + + + + + {filtered.length === 0 ? ( + +
+ + Tidak ditemukan + + + Coba gunakan kata kunci lain atau setel ulang filter. + + +
+
+ ) : ( + filtered.map((v) => ( + + + + +
+ + {React.createElement(v.icon, { + color: '#2563eb', + size: 34, + stroke: 1.6, + })} + +
+ + + + + {v.jumlah.toLocaleString()} + + + + {v.nama} + + + + + + + + + +
+ + + + +
+
+
+ )) + )} +
+
+
+
+ ); +} diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/lembaga/page.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/lembaga/page.tsx new file mode 100644 index 00000000..7d322bcb --- /dev/null +++ b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/lembaga/page.tsx @@ -0,0 +1,109 @@ +'use client' +import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud'; +import colors from '@/con/colors'; +import { Box, Center, Group, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; +import { IconSchool, IconLayersSubtract } from '@tabler/icons-react'; +import { useShallowEffect } from '@mantine/hooks'; +import { useProxy } from 'valtio/utils'; +import { use } from 'react'; + + +interface PageProps { + params: Promise<{ jenjangPendidikan: string }> +} + +function Page({ params }: PageProps) { + const stateList = useProxy(infoSekolahPaud.lembagaPendidikan) + const { jenjangPendidikan } = use(params); + + const { + data, + page, + totalPages, + loading, + load, + } = stateList.findMany + + useShallowEffect(() => { + // Decode the URL parameter and pass it to load + const decodedJenjang = decodeURIComponent(jenjangPendidikan).toLowerCase() + load(page, 10, '', decodedJenjang === 'semua' ? '' : decodedJenjang) + }, [page, jenjangPendidikan]) + + const filteredData = data || [] + + if (loading || !data) { + return ( + + + + + ) + } + + return ( + + + + + + Daftar Lembaga Pendidikan + + + + {filteredData.length === 0 ? ( + + + Belum ada data lembaga pendidikan + + ) : ( + + + + Nama Lembaga + Jenjang Pendidikan + + + + {filteredData.map((item) => ( + + {item.nama} + {item.jenjangPendidikan?.nama || '-'} + + ))} + +
+ )} +
+ + {filteredData.length > 0 && ( +
+ load(newPage)} + total={totalPages} + size="md" + radius="xl" + withEdges + /> +
+ )} +
+ ); +} + +export default Page; diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/page.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/page.tsx new file mode 100644 index 00000000..b65a3ca1 --- /dev/null +++ b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/page.tsx @@ -0,0 +1,14 @@ +// src/app/darmasaba/(pages)/desa/berita/[kategori]/page.tsx +import { Suspense } from "react"; +import Content from "./content"; + + +export default async function Page({ params }: { params: Promise<{ jenjangPendidikan: string }> }) { + const { jenjangPendidikan } = await params; + + return ( + Loading...}> + + + ); +} \ No newline at end of file diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/pengajar/page.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/pengajar/page.tsx new file mode 100644 index 00000000..9f1a9280 --- /dev/null +++ b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/pengajar/page.tsx @@ -0,0 +1,111 @@ +'use client' +import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud'; +import colors from '@/con/colors'; +import { Box, Center, Group, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; +import { IconSchool, IconLayersSubtract } from '@tabler/icons-react'; +import { useShallowEffect } from '@mantine/hooks'; +import { useProxy } from 'valtio/utils'; +import { use } from 'react'; + + +interface PageProps { + params: Promise<{ jenjangPendidikan: string }> +} + +function Page({ params }: PageProps) { + const stateList = useProxy(infoSekolahPaud.pengajar) + const { jenjangPendidikan } = use(params); + + const { + data, + page, + totalPages, + loading, + load, + } = stateList.findMany + + useShallowEffect(() => { + // Decode the URL parameter and pass it to load + const decodedJenjang = decodeURIComponent(jenjangPendidikan).toLowerCase() + load(page, 10, '', decodedJenjang === 'semua' ? '' : decodedJenjang) + }, [page, jenjangPendidikan]) + + const filteredData = data || [] + + if (loading || !data) { + return ( + + + + + ) + } + + return ( + + + + + + Daftar Pengajar + + + + {filteredData.length === 0 ? ( + + + Belum ada data pengajar + + ) : ( + + + + Nama Pengajar + Nama Lembaga + Jenjang Pendidikan + + + + {filteredData.map((item) => ( + + {item.nama} + {item.lembaga.nama} + {item.lembaga.jenjangPendidikan?.nama || '-'} + + ))} + +
+ )} +
+ + {filteredData.length > 0 && ( +
+ load(newPage)} + total={totalPages} + size="md" + radius="xl" + withEdges + /> +
+ )} +
+ ); +} + +export default Page; diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/siswa/page.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/siswa/page.tsx new file mode 100644 index 00000000..02b893e8 --- /dev/null +++ b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/[jenjangPendidikan]/siswa/page.tsx @@ -0,0 +1,111 @@ +'use client' +import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud'; +import colors from '@/con/colors'; +import { Box, Center, Group, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; +import { IconSchool, IconLayersSubtract } from '@tabler/icons-react'; +import { useShallowEffect } from '@mantine/hooks'; +import { useProxy } from 'valtio/utils'; +import { use } from 'react'; + + +interface PageProps { + params: Promise<{ jenjangPendidikan: string }> +} + +function Page({ params }: PageProps) { + const stateList = useProxy(infoSekolahPaud.siswa) + const { jenjangPendidikan } = use(params); + + const { + data, + page, + totalPages, + loading, + load, + } = stateList.findMany + + useShallowEffect(() => { + // Decode the URL parameter and pass it to load + const decodedJenjang = decodeURIComponent(jenjangPendidikan).toLowerCase() + load(page, 10, '', decodedJenjang === 'semua' ? '' : decodedJenjang) + }, [page, jenjangPendidikan]) + + const filteredData = data || [] + + if (loading || !data) { + return ( + + + + + ) + } + + return ( + + + + + + Daftar Siswa + + + + {filteredData.length === 0 ? ( + + + Belum ada data siswa + + ) : ( + + + + Nama Siswa + Nama Lembaga + Jenjang Pendidikan + + + + {filteredData.map((item) => ( + + {item.nama} + {item.lembaga.nama} + {item.lembaga.jenjangPendidikan?.nama || '-'} + + ))} + +
+ )} +
+ + {filteredData.length > 0 && ( +
+ load(newPage)} + total={totalPages} + size="md" + radius="xl" + withEdges + /> +
+ )} +
+ ); +} + +export default Page; diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/_lib/layoutTabs.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/_lib/layoutTabs.tsx new file mode 100644 index 00000000..f08919c1 --- /dev/null +++ b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/_lib/layoutTabs.tsx @@ -0,0 +1,127 @@ +'use client' +import colors from '@/con/colors'; +import { + ActionIcon, + Box, + Button, + Container, + Group, + Paper, + Stack, + Text, + TextInput, + VisuallyHidden, +} from '@mantine/core'; +import { IconArrowLeft, IconSearch } from '@tabler/icons-react'; +import { usePathname, useRouter, useSearchParams } from 'next/navigation'; +import React, { useState, useEffect } from 'react'; + +type LayoutSekolahProps = { + title?: string; + jenjangPendidikanList?: string[]; + children: React.ReactNode; +}; + +export default function LayoutSekolah({ + title = 'Cari Informasi Sekolah', + jenjangPendidikanList = ['Semua', 'TK', 'SD', 'SMP', 'SMA'], + children, +}: LayoutSekolahProps) { + const router = useRouter(); + const searchParams = useSearchParams(); + const pathname = usePathname(); + + const initialQuery = searchParams.get('search') || ''; + const initialJenjangPendidikan = searchParams.get('jenjangPendidikan') || 'Semua'; + + const [query, setQuery] = useState(initialQuery); + const [jenjangPendidikanAktif, setJenjangPendidikanAktif] = useState(initialJenjangPendidikan); + const [searchTimeout, setSearchTimeout] = useState(null); + + // Cleanup timeout + useEffect(() => { + return () => { + if (searchTimeout) clearTimeout(searchTimeout); + }; + }, [searchTimeout]); + + // Handle Search with debounce + const handleSearchChange = (e: React.ChangeEvent) => { + const val = e.target.value; + + setQuery(val); + + if (searchTimeout) clearTimeout(searchTimeout); + const t = window.setTimeout(() => { + const params = new URLSearchParams(searchParams.toString()); + if (val) params.set('search', val); + else params.delete('search'); + params.set('jenjangPendidikan', jenjangPendidikanAktif); + router.push(`${pathname}?${params.toString()}`); + }, 500); + setSearchTimeout(t); + }; + + // Handle jenjang pendidikan click + const handleJenjangPendidikanChange = (k: string) => { + // arahkan langsung ke route jenjang pendidikan + if (k.toLowerCase() === 'semua') { + setJenjangPendidikanAktif(k); + router.push(`/darmasaba/pendidikan/info-sekolah-paud/semua`); + } else { + setJenjangPendidikanAktif(k); + router.push(`/darmasaba/pendidikan/info-sekolah-paud/${encodeURIComponent(k.toLowerCase())}`); + } + }; + + + return ( + + + + {/* Back Button */} + window.history.back()} variant="light" radius="md" size="lg"> + + Kembali + + + {/* Search & Filter */} + + + {title} + + } + radius="xl" + size="md" + /> + + + {jenjangPendidikanList.map((k) => { + const aktif = k === jenjangPendidikanAktif; + return ( + + ); + })} + + + + + {/* Slot konten */} + {children} + + + + ); +} diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/layout.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/layout.tsx new file mode 100644 index 00000000..f41865b4 --- /dev/null +++ b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/layout.tsx @@ -0,0 +1,18 @@ +'use client' +import dynamic from 'next/dynamic'; +import React from 'react'; + +const LayoutSekolah = dynamic( + () => import('./_lib/layoutTabs'), + { ssr: false } +); + +function Layout({children} : {children: React.ReactNode}) { + return ( + + {children} + + ); +} + +export default Layout; diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/page.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/page.tsx deleted file mode 100644 index 88b61cff..00000000 --- a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/page.tsx +++ /dev/null @@ -1,363 +0,0 @@ -/* eslint-disable react-hooks/exhaustive-deps */ -'use client' -import React, { useMemo, useState } from 'react'; -import { - ActionIcon, - Badge, - Box, - Button, - Center, - Container, - Group, - Paper, - Progress, - SimpleGrid, - Stack, - Text, - TextInput, - Tooltip, - VisuallyHidden, -} from '@mantine/core'; -import { - IconChalkboard, - IconInfoCircle, - IconMicroscope, - IconSchool, - IconSearch, - IconArrowLeft, -} from '@tabler/icons-react'; -import { motion } from 'framer-motion'; -import type { IconProps } from '@tabler/icons-react'; - -type Stat = { - id: number; - icon: React.ComponentType; - jumlah: number; - nama: string; - helper?: string; -}; - -const dataSekolah: Stat[] = [ - { - id: 1, - icon: IconChalkboard, - jumlah: 15, - nama: 'Lembaga Pendidikan', - helper: 'Jumlah institusi pendidikan resmi di wilayah ini', - }, - { - id: 2, - icon: IconSchool, - jumlah: 3209, - nama: 'Siswa Terdaftar', - helper: 'Total siswa aktif di semua jenjang', - }, - { - id: 3, - icon: IconMicroscope, - jumlah: 285, - nama: 'Tenaga Pengajar', - helper: 'Jumlah guru dan staf pengajar aktif', - }, -]; - -export default function SekolahPage() { - const [query, setQuery] = useState(''); - const [kategoriAktif, setKategoriAktif] = useState('Semua'); - const kategoriList = ['Semua', 'TK/PAUD', 'SD', 'SMP', 'SMA/SMK']; - const maxJumlah = useMemo(() => Math.max(...dataSekolah.map((d) => d.jumlah)), []); - const filtered = useMemo(() => { - const q = query.trim().toLowerCase(); - return dataSekolah.filter((d) => { - const teks = `${d.nama} ${d.jumlah}`.toLowerCase(); - const matchQuery = q ? teks.includes(q) : true; - return matchQuery; - }); - }, [query, kategoriAktif]); - - const hasilCount = filtered.length; - - return ( - - - - - window.history.back()} - size="lg" - radius="md" - variant="light" - style={{ - color: '#1e293b', - background: 'white', - boxShadow: '0 2px 12px rgba(0,0,0,0.06)', - }} - > - - Tombol kembali - - - - - -
- - - Cari Informasi Sekolah - - - Masukkan nama, jenjang, atau alamat sekolah untuk hasil lebih spesifik. - - -
- - - setQuery(e.currentTarget.value)} - placeholder="Contoh: SMP Negeri, SD 01, Kelurahan..." - leftSection={} - aria-label="Masukkan kata kunci pencarian" - radius="xl" - size="md" - rightSection={ - - } - rightSectionWidth={120} - style={{ - width: '100%', - maxWidth: 920, - }} - /> - - - - {kategoriList.map((k) => { - const aktif = k === kategoriAktif; - return ( - - - - ); - })} - -
-
- - - - Menampilkan {hasilCount} hasil. - - - - - {filtered.length === 0 ? ( - -
- - Tidak ditemukan - - - Coba gunakan kata kunci lain atau setel ulang filter. - - -
-
- ) : ( - filtered.map((v) => { - const percent = Math.round((v.jumlah / maxJumlah) * 100) || 0; - return ( - - - -
- - {React.createElement(v.icon, { - color: '#2563eb', - size: 34, - stroke: 1.6, - })} - -
- - - - - {v.jumlah.toLocaleString()} - - - - {v.nama} - - - - - - - - - - - Statistik - - - - - - - Perbandingan dengan jumlah terbesar. - - -
- - - - -
-
- ); - }) - )} -
-
-
-
- ); -} diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/lembaga/page.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/lembaga/page.tsx new file mode 100644 index 00000000..8de4fc02 --- /dev/null +++ b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/lembaga/page.tsx @@ -0,0 +1,100 @@ +'use client' +import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud'; +import colors from '@/con/colors'; +import { Box, Center, Group, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; +import { IconSchool, IconLayersSubtract } from '@tabler/icons-react'; +import { useShallowEffect } from '@mantine/hooks'; +import { useProxy } from 'valtio/utils'; + +function Page() { + const stateList = useProxy(infoSekolahPaud.lembagaPendidikan) + + const { + data, + page, + totalPages, + loading, + load, + } = stateList.findMany + + useShallowEffect(() => { + load(page, 10) + }, [page]) + + const filteredData = data || [] + + if (loading || !data) { + return ( + + + + + ) + } + + return ( + + + + + + Daftar Lembaga Pendidikan + + + + {filteredData.length === 0 ? ( + + + Belum ada data lembaga pendidikan + + ) : ( + + + + Nama Lembaga + Jenjang Pendidikan + + + + {filteredData.map((item) => ( + + {item.nama} + {item.jenjangPendidikan?.nama || '-'} + + ))} + +
+ )} +
+ + {filteredData.length > 0 && ( +
+ load(newPage)} + total={totalPages} + size="md" + radius="xl" + withEdges + /> +
+ )} +
+ ); +} + +export default Page; diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/page.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/page.tsx new file mode 100644 index 00000000..67ca59ad --- /dev/null +++ b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/page.tsx @@ -0,0 +1,271 @@ +/* eslint-disable react-hooks/exhaustive-deps */ +'use client' +import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud'; +import { + ActionIcon, + Box, + Button, + Center, + Container, + Group, + Paper, + SimpleGrid, + Skeleton, + Stack, + Text, + Tooltip, +} from '@mantine/core'; +import type { IconProps } from '@tabler/icons-react'; +import { + IconChalkboard, + IconInfoCircle, + IconMicroscope, + IconRefresh, + IconSchool, +} from '@tabler/icons-react'; +import { motion } from 'framer-motion'; +import { useTransitionRouter } from 'next-view-transitions'; +import React, { useEffect, useState } from 'react'; +import { useProxy } from 'valtio/utils'; + +type Stat = { + icon: React.ComponentType; + jumlah: number; + nama: string; + helper?: string; + loading?: boolean; +}; + +export default function SekolahPage() { + const [stats, setStats] = useState([ + { + icon: IconChalkboard, + jumlah: 0, + nama: 'Lembaga Pendidikan', + helper: 'Jumlah institusi pendidikan resmi di wilayah ini', + loading: true, + }, + { + icon: IconSchool, + jumlah: 0, + nama: 'Siswa Terdaftar', + helper: 'Total siswa aktif di semua jenjang', + loading: true, + }, + { + icon: IconMicroscope, + jumlah: 0, + nama: 'Tenaga Pengajar', + helper: 'Jumlah guru dan staf pengajar aktif', + loading: true, + }, + ]); + const router = useTransitionRouter() + const stateLembaga = useProxy(infoSekolahPaud.lembagaPendidikan); + const stateSiswa = useProxy(infoSekolahPaud.siswa); + const statePengajar = useProxy(infoSekolahPaud.pengajar); + const loadData = async () => { + try { + // Load lembaga data + await stateLembaga.findMany.load(1, 1, ''); + const totalLembaga = stateLembaga.findMany.total || 0; + + // Load siswa data + await stateSiswa.findMany.load(1, 1, ''); + const totalSiswa = stateSiswa.findMany.total || 0; + + // Load pengajar data + await statePengajar.findMany.load(1, 1, ''); + const totalPengajar = statePengajar.findMany.total || 0; + + setStats([ + { + icon: IconChalkboard, + jumlah: totalLembaga, + nama: 'Lembaga Pendidikan', + helper: 'Jumlah institusi pendidikan resmi di wilayah ini', + loading: false, + }, + { + icon: IconSchool, + jumlah: totalSiswa, + nama: 'Siswa Terdaftar', + helper: 'Total siswa aktif di semua jenjang', + loading: false, + }, + { + icon: IconMicroscope, + jumlah: totalPengajar, + nama: 'Tenaga Pengajar', + helper: 'Jumlah guru dan staf pengajar aktif', + loading: false, + }, + ]); + } catch (error) { + console.error('Error loading data:', error); + // Set error state or show toast notification + } + }; + + useEffect(() => { + loadData(); + }, []); + + const handleRefresh = () => { + setStats(prev => prev.map(stat => ({ ...stat, loading: true }))); + loadData(); + }; + const [query] = useState(''); + + const filtered = stats.filter((d) => { + const q = query.trim().toLowerCase(); + if (!q) return true; + const teks = `${d.nama} ${d.jumlah}`.toLowerCase(); + return teks.includes(q); + }); + + return ( + + + + + + + + + {filtered.length === 0 ? ( + +
+ + Tidak ditemukan + + + Coba gunakan kata kunci lain atau setel ulang filter. + + +
+
+ ) : ( + filtered.map((v) => ( + + + + +
+ + {React.createElement(v.icon, { + color: '#2563eb', + size: 34, + stroke: 1.6, + })} + +
+ + + + + {v.jumlah.toLocaleString()} + + + + {v.nama} + + + + + + + + + +
+ + + + +
+
+
+ )) + )} +
+
+
+
+ ); +} diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/pengajar/page.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/pengajar/page.tsx new file mode 100644 index 00000000..0e38b4d5 --- /dev/null +++ b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/pengajar/page.tsx @@ -0,0 +1,102 @@ +'use client' +import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud'; +import colors from '@/con/colors'; +import { Box, Center, Group, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; +import { IconSchool, IconLayersSubtract } from '@tabler/icons-react'; +import { useShallowEffect } from '@mantine/hooks'; +import { useProxy } from 'valtio/utils'; + +function Page() { + const stateList = useProxy(infoSekolahPaud.pengajar) + + const { + data, + page, + totalPages, + loading, + load, + } = stateList.findMany + + useShallowEffect(() => { + load(page, 10) + }, [page]) + + const filteredData = data || [] + + if (loading || !data) { + return ( + + + + + ) + } + + return ( + + + + + + Daftar Pengajar + + + + {filteredData.length === 0 ? ( + + + Belum ada data pengajar + + ) : ( + + + + Nama Pengajar + Nama Lembaga + Jenjang Pendidikan + + + + {filteredData.map((item) => ( + + {item.nama} + {item.lembaga.nama} + {item.lembaga.jenjangPendidikan?.nama || '-'} + + ))} + +
+ )} +
+ + {filteredData.length > 0 && ( +
+ load(newPage)} + total={totalPages} + size="md" + radius="xl" + withEdges + /> +
+ )} +
+ ); +} + +export default Page; diff --git a/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/siswa/page.tsx b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/siswa/page.tsx new file mode 100644 index 00000000..149d398d --- /dev/null +++ b/src/app/darmasaba/(pages)/pendidikan/info-sekolah-paud/semua/siswa/page.tsx @@ -0,0 +1,102 @@ +'use client' +import infoSekolahPaud from '@/app/admin/(dashboard)/_state/pendidikan/info-sekolah-paud'; +import colors from '@/con/colors'; +import { Box, Center, Group, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core'; +import { IconSchool, IconLayersSubtract } from '@tabler/icons-react'; +import { useShallowEffect } from '@mantine/hooks'; +import { useProxy } from 'valtio/utils'; + +function Page() { + const stateList = useProxy(infoSekolahPaud.siswa) + + const { + data, + page, + totalPages, + loading, + load, + } = stateList.findMany + + useShallowEffect(() => { + load(page, 10) + }, [page]) + + const filteredData = data || [] + + if (loading || !data) { + return ( + + + + + ) + } + + return ( + + + + + + Daftar Siswa + + + + {filteredData.length === 0 ? ( + + + Belum ada data siswa + + ) : ( + + + + Nama Siswa + Nama Lembaga + Jenjang Pendidikan + + + + {filteredData.map((item) => ( + + {item.nama} + {item.lembaga.nama} + {item.lembaga.jenjangPendidikan?.nama || '-'} + + ))} + +
+ )} +
+ + {filteredData.length > 0 && ( +
+ load(newPage)} + total={totalPages} + size="md" + radius="xl" + withEdges + /> +
+ )} +
+ ); +} + +export default Page; diff --git a/src/con/navbar-list-menu.ts b/src/con/navbar-list-menu.ts index 0ff3d936..d350661e 100644 --- a/src/con/navbar-list-menu.ts +++ b/src/con/navbar-list-menu.ts @@ -307,7 +307,7 @@ const navbarListMenu = [ { id: "8.1", name: "Info Sekolah & PAUD", - href: "/darmasaba/pendidikan/info-sekolah-paud" + href: "/darmasaba/pendidikan/info-sekolah-paud/semua" }, { id: "8.2",