Merge pull request 'nico/21-jan-26' (#51) from nico/21-jan-26 into staggingweb

Reviewed-on: http://wibugit.wibudev.com/wibu/desa-darmasaba/pulls/51
This commit is contained in:
2026-01-21 12:10:18 +08:00
60 changed files with 1854 additions and 316 deletions

View File

@@ -41,6 +41,7 @@ import {
IconMessageReport,
IconUsers,
IconQuestionMark,
IconBook,
} from '@tabler/icons-react'
/* =======================
@@ -90,6 +91,7 @@ export type IconKey =
| 'informasi'
| 'pengaduan'
| 'layananPublik'
| 'book'
/* =======================
Icon Map
@@ -138,6 +140,7 @@ const iconMap: Record<IconKey, React.FC<any>> = {
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
}
/* =======================

View File

@@ -5,6 +5,7 @@ import { Box, rem, Select } from '@mantine/core';
import {
IconAlertTriangle,
IconAmbulance,
IconBook,
IconBuilding,
IconBuildingCommunity,
IconCash,
@@ -85,6 +86,7 @@ const iconMap = {
informasi: { label: 'Informasi', icon: IconInfoCircle },
pengaduan: { label: 'Pengaduan', icon: IconMessageReport },
layananPublik: { label: 'Layanan Publik', icon: IconUsers },
book: { label: 'Buku', icon: IconBook }
};

View File

@@ -37,6 +37,7 @@ import {
IconShield,
IconStethoscope,
IconUsers,
IconBook,
} from '@tabler/icons-react';
const iconMap = {
@@ -83,6 +84,7 @@ const iconMap = {
informasi: { label: 'Informasi', icon: IconInfoCircle },
pengaduan: { label: 'Pengaduan', icon: IconMessageReport },
layananPublik: { label: 'Layanan Publik', icon: IconUsers },
book: { label: 'Buku', icon: IconBook }
};
export type IconKey = keyof typeof iconMap;

View File

@@ -222,7 +222,6 @@ function ListKategoriBerita({ search }: { search: string }) {
</Stack>
</Paper>
{totalPages > 1 && (
<Center mt={{ base: 'lg', md: 'xl' }}>
<Pagination
value={page}
@@ -235,7 +234,6 @@ function ListKategoriBerita({ search }: { search: string }) {
radius="md"
/>
</Center>
)}
{/* Modal Konfirmasi Hapus */}
<ModalKonfirmasiHapus

View File

@@ -186,7 +186,6 @@ function ListAjukanPermohonan({ search }: { search: string }) {
</Box>
</Paper>
{totalPages > 1 && (
<Center mt="md">
<Pagination
value={page}
@@ -199,7 +198,6 @@ function ListAjukanPermohonan({ search }: { search: string }) {
radius="md"
/>
</Center>
)}
</Box>
);
}

View File

@@ -267,8 +267,6 @@ function ListPendapatan({ search }: { search: string }) {
</Stack>
</Paper>
{/* Pagination */}
{totalPages > 1 && (
<Center mt={{ base: 'sm', md: 'md' }} mb={{ base: 'sm', md: 'md' }}>
<Pagination
value={page}
@@ -282,7 +280,6 @@ function ListPendapatan({ search }: { search: string }) {
size="sm"
/>
</Center>
)}
{/* Modal Konfirmasi Hapus */}
<ModalKonfirmasiHapus

View File

@@ -284,7 +284,6 @@ function ListPosisiOrganisasiBumDes({ search }: { search: string }) {
</Box>
</Paper>
{totalPages > 1 && (
<Center>
<Pagination
value={page}
@@ -299,7 +298,6 @@ function ListPosisiOrganisasiBumDes({ search }: { search: string }) {
radius="md"
/>
</Center>
)}
{/* Modal Hapus */}
<ModalKonfirmasiHapus

View File

@@ -224,7 +224,6 @@ function ListDetailDataPengangguran({ search }: { search: string }) {
</Paper>
{/* Pagination */}
{totalPages > 1 && (
<Center>
<Pagination
value={page}
@@ -239,7 +238,6 @@ function ListDetailDataPengangguran({ search }: { search: string }) {
radius="md"
/>
</Center>
)}
{/* Chart Section */}
<Paper withBorder bg={colors['white-1']} p={{ base: 'sm', md: 'lg' }} shadow="md" radius="md">

View File

@@ -84,6 +84,13 @@ function CreateProgramKreatifDesa() {
required
/>
<TextInput
label={<Text fz="sm" fw="bold">Deskripsi Singkat</Text>}
placeholder="Masukkan deskripsi singkat"
value={stateCreate.create.form.slug || ''}
onChange={(e) => stateCreate.create.form.slug = e.currentTarget.value}
/>
<YearPickerInput
clearable
value={stateCreate.create.form.tahun ? new Date(stateCreate.create.form.tahun, 0, 1) : null}
@@ -95,6 +102,13 @@ function CreateProgramKreatifDesa() {
}}
/>
<TextInput
label={<Text fz="sm" fw="bold">Kolaborator</Text>}
placeholder="Masukkan kolaborator"
value={stateCreate.create.form.kolaborator || ''}
onChange={(e) => stateCreate.create.form.kolaborator = e.currentTarget.value}
/>
<Box>
<Text fw="bold" fz="sm" mb={6}>
Deskripsi
@@ -103,14 +117,7 @@ function CreateProgramKreatifDesa() {
value={stateCreate.create.form.deskripsi}
onChange={(val) => stateCreate.create.form.deskripsi = val}
/>
</Box>
<TextInput
label={<Text fz="sm" fw="bold">Kolaborator</Text>}
placeholder="Masukkan kolaborator"
value={stateCreate.create.form.kolaborator || ''}
onChange={(e) => stateCreate.create.form.kolaborator = e.currentTarget.value}
/>
</Box>
<Group justify="right" mt="md">
<Button

View File

@@ -245,7 +245,6 @@ function ListKolaborasiInovasi({ search }: { search: string }) {
</Box>
</Paper>
{totalPages > 1 && (
<Center>
<Pagination
value={page}
@@ -260,7 +259,6 @@ function ListKolaborasiInovasi({ search }: { search: string }) {
radius="md"
/>
</Center>
)}
</Box>
);
}

View File

@@ -20,14 +20,14 @@ import {
Text,
Title,
} from '@mantine/core';
import { IconEdit, IconPlus, IconSearch, IconX } from '@tabler/icons-react';
import { useDebouncedValue } from '@mantine/hooks';
import { IconEdit, IconPlus, IconSearch, IconTrash, IconX } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import { useProxy } from 'valtio/utils';
import HeaderSearch from '../../../_com/header';
import { ModalKonfirmasiHapus } from '../../../_com/modalKonfirmasiHapus';
import mitraKolaborasi from '../../../_state/inovasi/mitra-kolaborasi';
import { useDebouncedValue } from '@mantine/hooks';
function MitraKolaborasi() {
const [search, setSearch] = useState('');
@@ -56,7 +56,6 @@ function ListMitraKolaborasi({ search }: { search: string }) {
mitraKolaborasi.delete.byId(selectedId);
setModalHapus(false);
setSelectedId(null);
router.push('/admin/inovasi/kolaborasi-inovasi');
}
};
@@ -192,7 +191,7 @@ function ListMitraKolaborasi({ search }: { search: string }) {
setModalHapus(true);
}}
>
<IconX size={16} />
<IconTrash size={16} />
</Button>
</TableTd>
<TableTd>

View File

@@ -234,7 +234,6 @@ function ListJenisLayanan({ search }: { search: string }) {
</Box>
</Paper>
{totalPages > 1 && (
<Center>
<Pagination
value={page}
@@ -248,7 +247,6 @@ function ListJenisLayanan({ search }: { search: string }) {
radius="md"
/>
</Center>
)}
</Stack>
);
}

View File

@@ -20,37 +20,53 @@ import {
Text,
Title,
} from '@mantine/core';
import { useDebouncedValue } from '@mantine/hooks';
import {
IconAlertTriangle,
IconAmbulance,
IconBook,
IconBuilding,
IconBuildingCommunity,
IconCash,
IconChartLine,
IconChristmasTreeFilled,
IconClipboard,
IconClipboardTextFilled,
IconDeviceImac,
IconDroplet,
IconFileText,
IconFiretruck,
IconFirstAidKit,
IconHome,
IconHomeEco,
IconHospital,
IconInfoCircle,
IconLeaf,
IconLifebuoy,
IconMessageReport,
IconPhoneCall,
IconPlus,
IconRecycle,
IconRun,
IconScale,
IconSchool,
IconSearch,
IconShield,
IconShieldFilled,
IconShoppingCart,
IconStethoscope,
IconTent,
IconTrash,
IconTrashFilled,
IconTree,
IconTrendingUp,
IconTrophy,
IconTruck,
IconTruckFilled,
IconUsers
} from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react';
import { useProxy } from 'valtio/utils';
import HeaderSearch from '../../_com/header';
import programKreatifState from '../../_state/inovasi/program-kreatif';
import { useDebouncedValue } from '@mantine/hooks';
function ProgramKreatifDesa() {
const [search, setSearch] = useState('');
@@ -81,15 +97,16 @@ function ListProgramKreatifDesa({ search }: { search: string }) {
const filteredData = data || [];
const iconMap: Record<string, React.FC<any>> = {
// ===== Umum & Lingkungan =====
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruck,
truck: IconTruckFilled,
scale: IconScale,
clipboard: IconClipboard,
trash: IconTrash,
clipboard: IconClipboardTextFilled,
trash: IconTrashFilled,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
@@ -101,6 +118,30 @@ function ListProgramKreatifDesa({ search }: { search: string }) {
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
// ===== Keamanan & Darurat =====
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
darurat: IconAlertTriangle,
sar: IconLifebuoy,
evakuasi: IconRun,
keamanan: IconShield,
teleponDarurat: IconPhoneCall,
// ===== Kesehatan =====
rumahSakit: IconHospital,
puskesmas: IconFirstAidKit,
klinik: IconStethoscope,
// ===== Pemerintahan & Fasilitas =====
bangunan: IconBuilding,
kantorDesa: IconBuildingCommunity,
administrasi: IconFileText,
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
};
if (loading || !data) {
@@ -132,7 +173,7 @@ function ListProgramKreatifDesa({ search }: { search: string }) {
</Button>
</Group>
<Box visibleFrom="md" style={{ overflowX: 'auto' }}>
<Box visibleFrom="md" style={{ overflowX: 'auto' }}>
<Table
highlightOnHover
miw={0}

View File

@@ -230,7 +230,6 @@ function ListKelahiran({ search }: { search: string }) {
</Paper>
{/* Pagination */}
{totalPages > 1 && (
<Center>
<Pagination
value={page}
@@ -245,7 +244,6 @@ function ListKelahiran({ search }: { search: string }) {
radius="md"
/>
</Center>
)}
</Stack>
);
}

View File

@@ -222,7 +222,6 @@ function ListKematian({ search }: { search: string }) {
</Paper>
{/* Pagination */}
{totalPages > 1 && (
<Center mt="lg">
<Pagination
value={page}
@@ -235,7 +234,6 @@ function ListKematian({ search }: { search: string }) {
radius="md"
/>
</Center>
)}
</Box>
);
}

View File

@@ -134,7 +134,6 @@ function ListKategoriPrestasi({ search }: { search: string }) {
</TableTbody>
</Table>
{totalPages > 1 && (
<Center mt="xl">
<Pagination
value={page}
@@ -151,7 +150,6 @@ function ListKategoriPrestasi({ search }: { search: string }) {
}}
/>
</Center>
)}
</Box>
{/* MOBILE: Card */}
@@ -194,7 +192,6 @@ function ListKategoriPrestasi({ search }: { search: string }) {
))
)}
{totalPages > 1 && (
<Center py="lg">
<Pagination
value={page}
@@ -211,7 +208,6 @@ function ListKategoriPrestasi({ search }: { search: string }) {
}}
/>
</Center>
)}
</Stack>
</Box>

View File

@@ -73,9 +73,9 @@ function ListPrestasi({ search }: { search: string }) {
{/* Desktop Table */}
<Box visibleFrom="md" style={{ overflowX: 'auto' }}>
<Table highlightOnHover
layout="fixed" // 🔥 PENTING
withColumnBorders={false} striped verticalSpacing="sm" miw={800}>
<Table highlightOnHover
layout="fixed" // 🔥 PENTING
withColumnBorders={false} striped verticalSpacing="sm" miw={800}>
<TableThead>
<TableTr>
<TableTh>Nama Prestasi</TableTh>
@@ -177,17 +177,15 @@ function ListPrestasi({ search }: { search: string }) {
</Stack>
</Paper>
{totalPages > 1 && (
<Center mt={{ base: 'md', md: 'lg' }}>
<Pagination
value={page}
onChange={load}
total={totalPages}
withEdges
size={isMobile ? 'xs' : 'sm'}
/>
</Center>
)}
<Center mt={{ base: 'md', md: 'lg' }}>
<Pagination
value={page}
onChange={load}
total={totalPages}
withEdges
size={isMobile ? 'xs' : 'sm'}
/>
</Center>
</Box>
)
}

View File

@@ -4,24 +4,45 @@ import colors from '@/con/colors';
import { Box, Button, Group, Paper, Skeleton, Stack, Text } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import {
IconAlertTriangle,
IconAmbulance,
IconArrowBack,
IconBook,
IconBuilding,
IconBuildingCommunity,
IconCash,
IconChartLine,
IconChristmasTreeFilled,
IconClipboard,
IconClipboardTextFilled,
IconDroplet,
IconEdit,
IconFileText,
IconFiretruck,
IconFirstAidKit,
IconHome,
IconHomeEco,
IconHospital,
IconInfoCircle,
IconLeaf,
IconLifebuoy,
IconMessageReport,
IconPhoneCall,
IconRecycle,
IconRun,
IconScale,
IconSchool,
IconShield,
IconShieldFilled,
IconShoppingCart,
IconStethoscope,
IconTent,
IconTrash,
IconTrashFilled,
IconTree,
IconTrendingUp,
IconTrophy,
IconTruck,
IconTruckFilled,
IconUsers
} from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation';
import React, { useState } from 'react';
@@ -36,24 +57,53 @@ function DetailDataLingkunganDesa() {
const params = useParams();
const [selectedId, setSelectedId] = useState<string | null>(null);
const iconMap: Record<string, React.FC<any>> = {
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruck,
scale: IconScale,
clipboard: IconClipboard,
trash: IconTrash,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
};
const iconMap: Record<string, React.FC<any>> = {
// ===== Umum & Lingkungan =====
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruckFilled,
scale: IconScale,
clipboard: IconClipboardTextFilled,
trash: IconTrashFilled,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
// ===== Keamanan & Darurat =====
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
darurat: IconAlertTriangle,
sar: IconLifebuoy,
evakuasi: IconRun,
keamanan: IconShield,
teleponDarurat: IconPhoneCall,
// ===== Kesehatan =====
rumahSakit: IconHospital,
puskesmas: IconFirstAidKit,
klinik: IconStethoscope,
// ===== Pemerintahan & Fasilitas =====
bangunan: IconBuilding,
kantorDesa: IconBuildingCommunity,
administrasi: IconFileText,
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
};
useShallowEffect(() => {
stateDataLingkungan.findUnique.load(params?.id as string);

View File

@@ -23,31 +23,43 @@ import {
import {
IconAlertTriangle,
IconAmbulance,
IconBook,
IconBuilding,
IconBuildingCommunity,
IconCash,
IconChartLine,
IconChristmasTreeFilled,
IconClipboardTextFilled,
IconDeviceImacCog,
IconDroplet,
IconFileText,
IconFiretruck,
IconFirstAidKit,
IconHome,
IconHomeEco,
IconHospital,
IconInfoCircle,
IconLeaf,
IconLifebuoy,
IconMessageReport,
IconPhoneCall,
IconPlus,
IconRecycle,
IconRun,
IconScale,
IconSchool,
IconSearch,
IconShield,
IconShieldFilled,
IconShoppingCart,
IconStethoscope,
IconTent,
IconTrashFilled,
IconTree,
IconTrendingUp,
IconTrophy,
IconTruckFilled,
IconUsers,
} from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react';
@@ -84,34 +96,53 @@ function ListDataLingkunganDesa({ search }: { search: string }) {
const filteredData = data || [];
const iconMap: Record<string, React.FC<any>> = {
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruckFilled,
scale: IconScale,
clipboard: IconClipboardTextFilled,
trash: IconTrashFilled,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
rumahSakit: IconHospital,
bangunan: IconBuilding,
darurat: IconAlertTriangle
};
const iconMap: Record<string, React.FC<any>> = {
// ===== Umum & Lingkungan =====
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruckFilled,
scale: IconScale,
clipboard: IconClipboardTextFilled,
trash: IconTrashFilled,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
// ===== Keamanan & Darurat =====
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
darurat: IconAlertTriangle,
sar: IconLifebuoy,
evakuasi: IconRun,
keamanan: IconShield,
teleponDarurat: IconPhoneCall,
// ===== Kesehatan =====
rumahSakit: IconHospital,
puskesmas: IconFirstAidKit,
klinik: IconStethoscope,
// ===== Pemerintahan & Fasilitas =====
bangunan: IconBuilding,
kantorDesa: IconBuildingCommunity,
administrasi: IconFileText,
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
};
if (loading || !data) {
return (

View File

@@ -2,7 +2,7 @@
import colors from '@/con/colors';
import { Box, Button, Center, Group, Pagination, Paper, Skeleton, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core';
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
import { IconAlertTriangle, IconAmbulance, IconBuilding, IconCash, IconChartLine, IconChristmasTreeFilled, IconClipboardTextFilled, IconDroplet, IconEdit, IconFiretruck, IconHome, IconHomeEco, IconHospital, IconLeaf, IconPlus, IconRecycle, IconScale, IconSchool, IconSearch, IconShieldFilled, IconShoppingCart, IconTent, IconTrashFilled, IconTree, IconTrendingUp, IconTrophy, IconTruckFilled } from '@tabler/icons-react';
import { IconAlertTriangle, IconAmbulance, IconBook, IconBuilding, IconBuildingCommunity, IconCash, IconChartLine, IconChristmasTreeFilled, IconClipboardTextFilled, IconDroplet, IconEdit, IconFileText, IconFiretruck, IconFirstAidKit, IconHome, IconHomeEco, IconHospital, IconInfoCircle, IconLeaf, IconLifebuoy, IconMessageReport, IconPhoneCall, IconPlus, IconRecycle, IconRun, IconScale, IconSchool, IconSearch, IconShield, IconShieldFilled, IconShoppingCart, IconStethoscope, IconTent, IconTrashFilled, IconTree, IconTrendingUp, IconTrophy, IconTruckFilled, IconUsers } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import React, { useState } from 'react';
import { useProxy } from 'valtio/utils';
@@ -58,32 +58,51 @@ function ListPengelolaanSampahBankSampah({ search }: { search: string }) {
const filteredData = data || []
const iconMap: Record<string, React.FC<{ size: number; style?: React.CSSProperties }>> = {
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruckFilled,
scale: IconScale,
clipboard: IconClipboardTextFilled,
trash: IconTrashFilled,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
rumahSakit: IconHospital,
bangunan: IconBuilding,
darurat: IconAlertTriangle,
// ===== Umum & Lingkungan =====
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruckFilled,
scale: IconScale,
clipboard: IconClipboardTextFilled,
trash: IconTrashFilled,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
// ===== Keamanan & Darurat =====
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
darurat: IconAlertTriangle,
sar: IconLifebuoy,
evakuasi: IconRun,
keamanan: IconShield,
teleponDarurat: IconPhoneCall,
// ===== Kesehatan =====
rumahSakit: IconHospital,
puskesmas: IconFirstAidKit,
klinik: IconStethoscope,
// ===== Pemerintahan & Fasilitas =====
bangunan: IconBuilding,
kantorDesa: IconBuildingCommunity,
administrasi: IconFileText,
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
};
if (loading || !data) {

View File

@@ -6,12 +6,14 @@ import { useShallowEffect } from '@mantine/hooks';
import {
IconAlertTriangle,
IconAmbulance,
IconArrowBack, IconBuilding, IconCash, IconChartLine, IconChristmasTreeFilled, IconClipboard,
IconArrowBack, IconBook, IconBuilding, IconBuildingCommunity, IconCash, IconChartLine, IconChristmasTreeFilled, IconClipboard,
IconDroplet,
IconEdit, IconFiretruck, IconHome, IconHomeEco, IconHospital, IconLeaf, IconRecycle, IconScale,
IconEdit, IconFileText, IconFiretruck, IconFirstAidKit, IconHome, IconHomeEco, IconHospital, IconInfoCircle, IconLeaf, IconLifebuoy, IconMessageReport, IconPhoneCall, IconRecycle, IconRun, IconScale,
IconSchool,
IconShieldFilled, IconShoppingCart, IconTent, IconTrash, IconTree, IconTrendingUp,
IconTrophy, IconTruck
IconShield,
IconShieldFilled, IconShoppingCart, IconStethoscope, IconTent, IconTrash, IconTree, IconTrendingUp,
IconTrophy, IconTruck,
IconUsers
} from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation';
import React, { useState } from 'react';
@@ -28,31 +30,49 @@ function DetailProgramPenghijauan() {
const iconMap: Record<string, React.FC<any>> = {
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruck,
scale: IconScale,
clipboard: IconClipboard,
trash: IconTrash,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
rumahSakit: IconHospital,
bangunan: IconBuilding,
darurat: IconAlertTriangle
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruck,
scale: IconScale,
clipboard: IconClipboard,
trash: IconTrash,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
// ===== Keamanan & Darurat =====
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
darurat: IconAlertTriangle,
sar: IconLifebuoy,
evakuasi: IconRun,
keamanan: IconShield,
teleponDarurat: IconPhoneCall,
// ===== Kesehatan =====
rumahSakit: IconHospital,
puskesmas: IconFirstAidKit,
klinik: IconStethoscope,
// ===== Pemerintahan =====
bangunan: IconBuilding,
kantorDesa: IconBuildingCommunity,
administrasi: IconFileText,
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
};
useShallowEffect(() => {
@@ -113,7 +133,7 @@ function DetailProgramPenghijauan() {
<Box>
<Text fz="lg" fw="bold">Ikon Program</Text>
{iconMap[data?.icon] ? (
{iconMap[data?.icon] ? (
<Box title={data?.icon}>
{React.createElement(iconMap[data.icon], { size: 28, color: colors['blue-button'] })}
</Box>

View File

@@ -23,31 +23,43 @@ import {
import {
IconAlertTriangle,
IconAmbulance,
IconBook,
IconBuilding,
IconBuildingCommunity,
IconCash,
IconChartLine,
IconChristmasTreeFilled,
IconClipboardTextFilled,
IconDeviceImac,
IconDroplet,
IconFileText,
IconFiretruck,
IconFirstAidKit,
IconHome,
IconHomeEco,
IconHospital,
IconInfoCircle,
IconLeaf,
IconLifebuoy,
IconMessageReport,
IconPhoneCall,
IconPlus,
IconRecycle,
IconRun,
IconScale,
IconSchool,
IconSearch,
IconShield,
IconShieldFilled,
IconShoppingCart,
IconStethoscope,
IconTent,
IconTrashFilled,
IconTree,
IconTrendingUp,
IconTrophy,
IconTruckFilled,
IconUsers,
} from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import React, { useEffect, useState } from 'react';
@@ -85,6 +97,7 @@ function ListProgramPenghijauan({ search }: { search: string }) {
const filteredData = data || [];
const iconMap: Record<string, React.FC<any>> = {
// ===== Umum & Lingkungan =====
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
@@ -105,12 +118,30 @@ function ListProgramPenghijauan({ search }: { search: string }) {
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
// ===== Keamanan & Darurat =====
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
rumahSakit: IconHospital,
bangunan: IconBuilding,
darurat: IconAlertTriangle,
sar: IconLifebuoy,
evakuasi: IconRun,
keamanan: IconShield,
teleponDarurat: IconPhoneCall,
// ===== Kesehatan =====
rumahSakit: IconHospital,
puskesmas: IconFirstAidKit,
klinik: IconStethoscope,
// ===== Pemerintahan & Fasilitas =====
bangunan: IconBuilding,
kantorDesa: IconBuildingCommunity,
administrasi: IconFileText,
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
};
if (loading || !data) {

View File

@@ -0,0 +1,7 @@
export default function serializeBigInt<T>(data: T): T {
return JSON.parse(
JSON.stringify(data, (_, value) =>
typeof value === "bigint" ? value.toString() : value
)
);
}

View File

@@ -40,6 +40,13 @@ function PengaduanMasyarakat() {
};
};
const resetAll = () => {
resetForm();
setFile(null);
setPreviewImage(null);
};
const handleSubmit = async () => {
if (!file) {
return toast.error("Silahkan pilih file gambar terlebih dahulu")
@@ -64,7 +71,7 @@ function PengaduanMasyarakat() {
const success = await state.pengaduanMasyarakat.create.create()
if (success) {
resetForm()
resetAll()
close()
}
} catch (error) {
@@ -190,7 +197,7 @@ function PengaduanMasyarakat() {
</Group>
</Dropzone>
{previewImage ? (
<Image alt="" src={previewImage} w={200} h={200} loading="lazy"/>
<Image alt="" src={previewImage} w={200} h={200} loading="lazy" />
) : (
<Center w={200} h={200} bg={"gray"}>
<IconImageInPicture />

View File

@@ -124,7 +124,6 @@ function ListPencegahanKriminalitas({ search }: { search: string }) {
)}
</Stack>
{totalPages > 1 && (
<Center>
<Pagination
value={page}
@@ -138,7 +137,6 @@ function ListPencegahanKriminalitas({ search }: { search: string }) {
radius="lg"
/>
</Center>
)}
</Box>
);
}

View File

@@ -179,7 +179,6 @@ export default function Page() {
))}
</SimpleGrid>
{totalPages > 1 && (
<Center>
<Pagination
value={page}
@@ -191,7 +190,6 @@ export default function Page() {
mt="md"
/>
</Center>
)}
<Stack gap="sm">
<Flex align="center" gap="xs">

View File

@@ -225,7 +225,6 @@ export default function Page() {
))}
</SimpleGrid>
{totalPages > 1 && (
<Center>
<Pagination
value={page}
@@ -242,7 +241,6 @@ export default function Page() {
}}
/>
</Center>
)}
</Box>
<Box px={{ base: "md", md: 100 }} py="xl">

View File

@@ -127,7 +127,6 @@ function Page() {
)}
</Box>
{totalPages > 1 && (
<Center>
<Pagination
value={page}
@@ -138,7 +137,6 @@ function Page() {
mt="lg"
/>
</Center>
)}
</Stack>
);
}

View File

@@ -3,7 +3,7 @@ import dataLingkunganDesaState from '@/app/admin/(dashboard)/_state/lingkungan/d
import colors from '@/con/colors';
import { Badge, Box, Center, Group, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Tooltip } from '@mantine/core';
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
import { Icon, IconChartLine, IconChristmasTreeFilled, IconClipboardTextFilled, IconDroplet, IconHome, IconHomeEco, IconLeaf, IconRecycle, IconScale, IconSearch, IconShieldFilled, IconTent, IconTrashFilled, IconTree, IconTrendingUp, IconTrophy, IconTruckFilled } from '@tabler/icons-react';
import { Icon, IconAlertTriangle, IconAmbulance, IconBook, IconBuilding, IconBuildingCommunity, IconCash, IconChartLine, IconChristmasTreeFilled, IconClipboard, IconDroplet, IconFileText, IconFiretruck, IconFirstAidKit, IconHome, IconHomeEco, IconHospital, IconInfoCircle, IconLeaf, IconLifebuoy, IconMessageReport, IconPhoneCall, IconRecycle, IconRun, IconScale, IconSchool, IconSearch, IconShield, IconShieldFilled, IconShoppingCart, IconStethoscope, IconTent, IconTrash, IconTree, IconTrendingUp, IconTrophy, IconTruck, IconUsers } from '@tabler/icons-react';
import React, { useState } from 'react';
import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
@@ -21,24 +21,51 @@ function Page() {
} = state
const iconMap: Record<string, Icon> = {
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruckFilled,
scale: IconScale,
clipboard: IconClipboardTextFilled,
trash: IconTrashFilled,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruck,
scale: IconScale,
clipboard: IconClipboard,
trash: IconTrash,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
};
// ===== Keamanan & Darurat =====
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
darurat: IconAlertTriangle,
sar: IconLifebuoy,
evakuasi: IconRun,
keamanan: IconShield,
teleponDarurat: IconPhoneCall,
// ===== Kesehatan =====
rumahSakit: IconHospital,
puskesmas: IconFirstAidKit,
klinik: IconStethoscope,
// ===== Pemerintahan =====
bangunan: IconBuilding,
kantorDesa: IconBuildingCommunity,
administrasi: IconFileText,
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
};
useShallowEffect(() => {
load(page, 6, debouncedSearch)

View File

@@ -3,11 +3,11 @@ import pengelolaanSampahState from '@/app/admin/(dashboard)/_state/lingkungan/pe
import colors from '@/con/colors';
import { Box, Center, Flex, Group, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput } from '@mantine/core';
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
import { Icon, IconChartLine, IconClipboardTextFilled, IconLeaf, IconRecycle, IconRoute, IconScale, IconSearch, IconTent, IconTrashFilled, IconTrophy, IconTruckFilled } from '@tabler/icons-react';
import { Icon, IconAlertTriangle, IconAmbulance, IconBook, IconBuilding, IconBuildingCommunity, IconCash, IconChartLine, IconChristmasTreeFilled, IconClipboard, IconDroplet, IconFileText, IconFiretruck, IconFirstAidKit, IconHome, IconHomeEco, IconHospital, IconInfoCircle, IconLeaf, IconLifebuoy, IconMessageReport, IconPhoneCall, IconRecycle, IconRoute, IconRun, IconScale, IconSchool, IconSearch, IconShield, IconShieldFilled, IconShoppingCart, IconStethoscope, IconTent, IconTrash, IconTree, IconTrendingUp, IconTrophy, IconTruck, IconUsers } from '@tabler/icons-react';
import dynamic from 'next/dynamic';
import React, { useState } from 'react';
import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
import dynamic from 'next/dynamic';
// Dynamically import the map component to avoid SSR issues with Leaflet
const LeafletMultiMarkerMap = dynamic(
@@ -42,16 +42,51 @@ function Page() {
}, [page, debouncedSearch])
const iconMap: Record<string, Icon> = {
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruckFilled,
scale: IconScale,
clipboard: IconClipboardTextFilled,
trash: IconTrashFilled,
};
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruck,
scale: IconScale,
clipboard: IconClipboard,
trash: IconTrash,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
// ===== Keamanan & Darurat =====
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
darurat: IconAlertTriangle,
sar: IconLifebuoy,
evakuasi: IconRun,
keamanan: IconShield,
teleponDarurat: IconPhoneCall,
// ===== Kesehatan =====
rumahSakit: IconHospital,
puskesmas: IconFirstAidKit,
klinik: IconStethoscope,
// ===== Pemerintahan =====
bangunan: IconBuilding,
kantorDesa: IconBuildingCommunity,
administrasi: IconFileText,
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
};
if (state.findMany.loading || !data) {
return (

View File

@@ -4,10 +4,21 @@ import programPenghijauanState from '@/app/admin/(dashboard)/_state/lingkungan/p
import { Box, Button, Paper, Skeleton, Stack, Text, ThemeIcon } from '@mantine/core';
import { useShallowEffect } from '@mantine/hooks';
import {
IconArrowLeft, IconChartLine, IconChristmasTreeFilled, IconClipboard,
IconHomeEco, IconLeaf, IconRecycle, IconScale,
IconShieldFilled, IconTent, IconTrash,
IconTrendingUp, IconTrophy, IconTruck
IconAlertTriangle,
IconAmbulance,
IconArrowLeft, IconBook, IconBuilding, IconBuildingCommunity, IconCash, IconChartLine, IconChristmasTreeFilled, IconClipboard,
IconDroplet,
IconFileText,
IconFiretruck,
IconFirstAidKit,
IconHome,
IconHomeEco, IconHospital, IconInfoCircle, IconLeaf, IconLifebuoy, IconMessageReport, IconPhoneCall, IconRecycle, IconRun, IconScale,
IconSchool,
IconShield,
IconShieldFilled, IconShoppingCart, IconStethoscope, IconTent, IconTrash,
IconTree,
IconTrendingUp, IconTrophy, IconTruck,
IconUsers
} from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation';
import React from 'react';
@@ -32,6 +43,37 @@ function Page() {
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
// ===== Keamanan & Darurat =====
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
darurat: IconAlertTriangle,
sar: IconLifebuoy,
evakuasi: IconRun,
keamanan: IconShield,
teleponDarurat: IconPhoneCall,
// ===== Kesehatan =====
rumahSakit: IconHospital,
puskesmas: IconFirstAidKit,
klinik: IconStethoscope,
// ===== Pemerintahan =====
bangunan: IconBuilding,
kantorDesa: IconBuildingCommunity,
administrasi: IconFileText,
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
};
useShallowEffect(() => {

View File

@@ -4,11 +4,11 @@ import programPenghijauanState from '@/app/admin/(dashboard)/_state/lingkungan/p
import colors from '@/con/colors';
import { Box, Center, Group, Pagination, Paper, SimpleGrid, Skeleton, Stack, Text, TextInput, Title, Tooltip } from '@mantine/core';
import { useDebouncedValue, useShallowEffect } from '@mantine/hooks';
import { IconChartLine, IconChristmasTreeFilled, IconClipboardTextFilled, IconHomeEco, IconLeaf, IconRecycle, IconScale, IconSearch, IconShieldFilled, IconTent, IconTrashFilled, IconTrendingUp, IconTrophy, IconTruckFilled } from '@tabler/icons-react';
import { IconAlertTriangle, IconAmbulance, IconBook, IconBuilding, IconBuildingCommunity, IconCash, IconChartLine, IconChristmasTreeFilled, IconClipboard, IconDroplet, IconFileText, IconFiretruck, IconFirstAidKit, IconHome, IconHomeEco, IconHospital, IconInfoCircle, IconLeaf, IconLifebuoy, IconMessageReport, IconPhoneCall, IconRecycle, IconRun, IconScale, IconSchool, IconSearch, IconShield, IconShieldFilled, IconShoppingCart, IconStethoscope, IconTent, IconTrash, IconTree, IconTrendingUp, IconTrophy, IconTruck, IconUsers } from '@tabler/icons-react';
import { useTransitionRouter } from 'next-view-transitions';
import React, { useState } from 'react';
import { useProxy } from 'valtio/utils';
import BackButton from '../../desa/layanan/_com/BackButto';
import { useTransitionRouter } from 'next-view-transitions';
function Page() {
const state = useProxy(programPenghijauanState);
@@ -22,20 +22,51 @@ function Page() {
}, [page, debouncedSearch]);
const iconMap: Record<string, any> = {
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruckFilled,
scale: IconScale,
clipboard: IconClipboardTextFilled,
trash: IconTrashFilled,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
};
ekowisata: IconLeaf,
kompetisi: IconTrophy,
wisata: IconTent,
ekonomi: IconChartLine,
sampah: IconRecycle,
truck: IconTruck,
scale: IconScale,
clipboard: IconClipboard,
trash: IconTrash,
lingkunganSehat: IconHomeEco,
sumberOksigen: IconChristmasTreeFilled,
ekonomiBerkelanjutan: IconTrendingUp,
mencegahBencana: IconShieldFilled,
rumah: IconHome,
pohon: IconTree,
air: IconDroplet,
bantuan: IconCash,
pelatihan: IconSchool,
subsidi: IconShoppingCart,
layananKesehatan: IconHospital,
// ===== Keamanan & Darurat =====
polisi: IconShieldFilled,
ambulans: IconAmbulance,
pemadam: IconFiretruck,
darurat: IconAlertTriangle,
sar: IconLifebuoy,
evakuasi: IconRun,
keamanan: IconShield,
teleponDarurat: IconPhoneCall,
// ===== Kesehatan =====
rumahSakit: IconHospital,
puskesmas: IconFirstAidKit,
klinik: IconStethoscope,
// ===== Pemerintahan =====
bangunan: IconBuilding,
kantorDesa: IconBuildingCommunity,
administrasi: IconFileText,
informasi: IconInfoCircle,
pengaduan: IconMessageReport,
layananPublik: IconUsers,
book: IconBook
};
if (loading || !data) {
return (