Add Fitur Search Di setiap menu

This commit is contained in:
2025-07-08 00:30:55 +08:00
parent 2725c2c064
commit 7e95d5fbb4
38 changed files with 792 additions and 182 deletions

View File

@@ -1,42 +1,46 @@
'use client'
import colors from '@/con/colors';
import { Box, Button, Grid, GridCol, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, TextInput, Title } from '@mantine/core';
import { Box, Button, Grid, GridCol, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import { IconCircleDashedPlus, IconDeviceImacCog, IconSearch } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import HeaderSearch from '../../_com/header';
import daftarInformasiPublik from '../../_state/ppid/daftar_informasi_publik/daftarInformasiPublik';
function Page() {
function DaftarInformasiPublik() {
const [search, setSearch] = useState("");
return (
<Box>
<Grid>
<GridCol span={{ base: 12, md: 9 }}>
<Title order={3}>Daftar Informasi Publik Desa Darmasaba</Title>
</GridCol>
<GridCol span={{ base: 12, md: 3 }}>
<Paper radius={"lg"} bg={colors['white-1']}>
<TextInput
radius={"lg"}
placeholder='pencarian'
leftSection={<IconSearch size={20} />}
/>
</Paper>
</GridCol>
</Grid>
<ListDaftarInformasi />
<HeaderSearch
title='Posisi Organisasi'
placeholder='pencarian'
searchIcon={<IconSearch size={20} />}
value={search}
onChange={(e) => setSearch(e.currentTarget.value)}
/>
<ListDaftarInformasi search={search} />
</Box>
);
}
function ListDaftarInformasi() {
function ListDaftarInformasi({ search }: { search: string }) {
const listData = useProxy(daftarInformasiPublik)
const router = useRouter()
useShallowEffect(() => {
listData.findMany.load()
}, [])
const router = useRouter()
const filteredData = (listData.findMany.data || []).filter(item => {
const keyword = search.toLowerCase();
return (
item.jenisInformasi.toLowerCase().includes(keyword) ||
item.deskripsi.toLowerCase().includes(keyword)
);
});
if (!listData.findMany.data) {
return (
@@ -77,7 +81,7 @@ function ListDaftarInformasi() {
</TableTr>
</TableThead>
<TableTbody>
{listData.findMany.data?.map((item, index) => (
{filteredData.map((item, index) => (
<TableTr key={item.id}>
<TableTd>{index + 1}</TableTd>
<TableTd>{item.jenisInformasi}</TableTd>
@@ -98,4 +102,4 @@ function ListDaftarInformasi() {
)
}
export default Page;
export default DaftarInformasiPublik;

View File

@@ -11,8 +11,25 @@ import { Cell, Pie, PieChart } from 'recharts';
import { useProxy } from 'valtio/utils';
import JudulListTab from '../../../_com/jusulListTab';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
import HeaderSearch from '../../../_com/header';
function GrafikBerdasarkanJenisKelamin() {
const [search, setSearch] = useState("");
return (
<Box>
<HeaderSearch
title='Grafik Berdasarkan Jenis Kelamin Responden'
placeholder='pencarian'
searchIcon={<IconSearch size={20} />}
value={search}
onChange={(e) => setSearch(e.currentTarget.value)}
/>
<ListGrafikBerdasarkanJenisKelamin search={search} />
</Box>
);
}
function ListGrafikBerdasarkanJenisKelamin({ search }: { search: string }) {
const stategrafikBerdasarkanJenisKelamin = useProxy(grafikBerdasarkanJenisKelamin)
const [donutData, setDonutData] = useState<any[]>([]);
const [mounted, setMounted] = useState(false);
@@ -46,6 +63,14 @@ function GrafikBerdasarkanJenisKelamin() {
}
}, [stategrafikBerdasarkanJenisKelamin.findMany.data])
const filteredData = (stategrafikBerdasarkanJenisKelamin.findMany.data || []).filter(item => {
const keyword = search.toLowerCase();
return (
item.laki.toString().toLowerCase().includes(keyword) ||
item.perempuan.toString().toLowerCase().includes(keyword)
);
});
if (!stategrafikBerdasarkanJenisKelamin.findMany.data) {
return (
<Box>
@@ -74,14 +99,14 @@ function GrafikBerdasarkanJenisKelamin() {
</TableTr>
</TableThead>
<TableTbody>
{stategrafikBerdasarkanJenisKelamin.findMany.data.length === 0 ? (
{filteredData.length === 0 ? (
<TableTr>
<TableTd colSpan={6}>
<Text ta='center' c='dimmed'>Belum ada data grafik responden</Text>
</TableTd>
</TableTr>
) : (
stategrafikBerdasarkanJenisKelamin.findMany.data.map((item) => (
filteredData.map((item) => (
<TableTr key={item.id}>
<TableTd>{item.laki}</TableTd>
<TableTd>{item.perempuan}</TableTd>

View File

@@ -11,9 +11,25 @@ import { useSnapshot } from 'valtio';
import JudulListTab from '../../../_com/jusulListTab';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
import grafikBerdasarkanResponden from '../../../_state/ppid/indeks_kepuasan_masyarakat/grafikBerdasarkanResponden';
import HeaderSearch from '../../../_com/header';
function GrafikBerdasarkanResponden() {
const [search, setSearch] = useState("");
return (
<Box>
<HeaderSearch
title='Grafik Berdasarkan Pilihan Responden'
placeholder='pencarian'
searchIcon={<IconSearch size={20} />}
value={search}
onChange={(e) => setSearch(e.currentTarget.value)}
/>
<ListGrafikBerdasarkanResponden search={search} />
</Box>
);
}
function ListGrafikBerdasarkanResponden({ search }: { search: string }) {
const stategrafikBerdasarkanResponden = useSnapshot(grafikBerdasarkanResponden)
const [donutData, setDonutData] = useState<any[]>([]);
const [mounted, setMounted] = useState(false);
@@ -38,6 +54,16 @@ function GrafikBerdasarkanResponden() {
stategrafikBerdasarkanResponden.findMany.load()
}, [])
const filteredData = (stategrafikBerdasarkanResponden.findMany.data || []).filter(item => {
const keyword = search.toLowerCase();
return (
item.sangatbaik.toString().toLowerCase().includes(keyword) ||
item.baik.toString().toLowerCase().includes(keyword) ||
item.kurangbaik.toString().toLowerCase().includes(keyword) ||
item.tidakbaik.toString().toLowerCase().includes(keyword)
);
});
useEffect(() => {
if (stategrafikBerdasarkanResponden.findMany.data) {
const totalSangatBaik = stategrafikBerdasarkanResponden.findMany.data.reduce((acc: number, cur: any) => acc + Number(cur.sangatbaik || 0), 0);
@@ -83,14 +109,14 @@ function GrafikBerdasarkanResponden() {
</TableTr>
</TableThead>
<TableTbody>
{stategrafikBerdasarkanResponden.findMany.data.length === 0 ? (
{filteredData.length === 0 ? (
<TableTr>
<TableTd colSpan={6}>
<Text ta='center' c='dimmed'>Belum ada data grafik responden</Text>
</TableTd>
</TableTr>
) : (
stategrafikBerdasarkanResponden.findMany.data.map((item) => (
filteredData.map((item) => (
<TableTr key={item.id}>
<TableTd>{item.sangatbaik}</TableTd>
<TableTd>{item.baik}</TableTd>

View File

@@ -11,8 +11,25 @@ import { Cell, Pie, PieChart } from 'recharts';
import { useProxy } from 'valtio/utils';
import JudulListTab from '../../../_com/jusulListTab';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
import HeaderSearch from '../../../_com/header';
function GrafikBerdasarakanUmur() {
const [search, setSearch] = useState("");
return (
<Box>
<HeaderSearch
title='Grafik Berdasarkan Umur Responden'
placeholder='pencarian'
searchIcon={<IconSearch size={20} />}
value={search}
onChange={(e) => setSearch(e.currentTarget.value)}
/>
<ListGrafikBerdasarakanUmur search={search} />
</Box>
);
}
function ListGrafikBerdasarakanUmur({ search }: { search: string }) {
const stategrafikBerdasarkanUmur = useProxy(grafikBerdasarkanUmur)
const [donutData, setDonutData] = useState<any[]>([]);
const [mounted, setMounted] = useState(false);
@@ -50,6 +67,16 @@ function GrafikBerdasarakanUmur() {
}
}, [stategrafikBerdasarkanUmur.findMany.data])
const filteredData = (stategrafikBerdasarkanUmur.findMany.data || []).filter(item => {
const keyword = search.toLowerCase();
return (
item.remaja.toString().toLowerCase().includes(keyword) ||
item.dewasa.toString().toLowerCase().includes(keyword) ||
item.orangtua.toString().toLowerCase().includes(keyword) ||
item.lansia.toString().toLowerCase().includes(keyword)
);
});
if (!stategrafikBerdasarkanUmur.findMany.data) {
return (
<Box>
@@ -57,7 +84,7 @@ function GrafikBerdasarakanUmur() {
</Box>
)
}
return (
<Box>
<Stack gap={"xs"}>
@@ -80,14 +107,14 @@ function GrafikBerdasarakanUmur() {
</TableTr>
</TableThead>
<TableTbody>
{stategrafikBerdasarkanUmur.findMany.data.length === 0 ? (
{filteredData.length === 0 ? (
<TableTr>
<TableTd colSpan={6}>
<Text ta='center' c='dimmed'>Belum ada data grafik responden</Text>
</TableTd>
</TableTr>
) : (
stategrafikBerdasarkanUmur.findMany.data.map((item) => (
filteredData.map((item) => (
<TableTr key={item.id}>
<TableTd>{item.remaja}</TableTd>
<TableTd>{item.dewasa}</TableTd>

View File

@@ -10,9 +10,26 @@ import { Bar, BarChart, Legend, Tooltip, XAxis, YAxis } from 'recharts';
import { useSnapshot } from 'valtio';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
import grafikHasilKepuasanMasyarakat from '../../../_state/ppid/indeks_kepuasan_masyarakat/grafikHasilKepuasan';
import HeaderSearch from '../../../_com/header';
function GrafikHasilKepuasanMasyarakat() {
const [search, setSearch] = useState("");
return (
<Box>
<HeaderSearch
title='Grafik Hasil Kepuasan Masyarakat'
placeholder='pencarian'
searchIcon={<IconSearch size={20} />}
value={search}
onChange={(e) => setSearch(e.currentTarget.value)}
/>
<ListGrafikHasilKepuasanMasyarakat search={search} />
</Box>
);
}
function ListGrafikHasilKepuasanMasyarakat({ search }: { search: string }) {
type IKMGrafik = {
id: string;
label: string;
@@ -58,6 +75,14 @@ function GrafikHasilKepuasanMasyarakat() {
}
}, [stateGrafikHasilKepuasan.findMany.data]);
const filteredData = (stateGrafikHasilKepuasan.findMany.data || []).filter(item => {
const keyword = search.toLowerCase();
return (
item.label.toLowerCase().includes(keyword) ||
item.kepuasan.toString().toLowerCase().includes(keyword)
);
});
if (!stateGrafikHasilKepuasan.findMany.data) {
@@ -87,7 +112,7 @@ function GrafikHasilKepuasanMasyarakat() {
</TableTr>
</TableThead>
<TableTbody>
{stateGrafikHasilKepuasan.findMany.data?.map((item) => (
{filteredData.map((item) => (
<TableTr key={item.id}>
<TableTd>{item.label}</TableTd>
<TableTd>{item.kepuasan}</TableTd>