Sinkronisasi UI & API Admin - User Submenu Demografi Pekerjaan, Menu Ekonomi

This commit is contained in:
2025-08-22 01:10:18 +08:00
parent 760ba4b6d2
commit 8469ebd2e1
5 changed files with 117 additions and 260 deletions

View File

@@ -143,8 +143,8 @@ function ListDemografiPekerjaan({ search }: { search: string }) {
dataKey="pekerjaan"
type="stacked"
series={[
{ name: 'lakiLaki', color: 'red.6', label: 'Laki - Laki' },
{ name: 'perempuan', color: 'orange.6', label: 'Perempuan' },
{ name: 'lakiLaki', color: '#5082EE', label: 'Laki - Laki' },
{ name: 'perempuan', color: '#6EDF9C', label: 'Perempuan' },
]}
/>
</Box>

View File

@@ -2,15 +2,16 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
'use client'
import colors from '@/con/colors';
import { Box, Button, Group, Paper, Stack, TextInput, Title } from '@mantine/core';
import { Box, Button, Group, Paper, Stack, Text, TextInput, Title } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { useProxy } from 'valtio/utils';
import grafikSektorUnggulan from '../../../_state/ekonomi/sektor-unggulan-desa';
import CreateEditor from '../../../_com/createEditor';
function CreateSektorUnggulanDesa() {
const stateGrafik= useProxy(grafikSektorUnggulan);
const stateGrafik = useProxy(grafikSektorUnggulan);
const [chartData, setChartData] = useState<any[]>([]);
const router = useRouter()
@@ -54,15 +55,15 @@ function CreateSektorUnggulanDesa() {
stateGrafik.create.form.name = val.currentTarget.value;
}}
/>
<TextInput
label="Deskripsi Sektor Unggulan"
type="text"
value={stateGrafik.create.form.description}
placeholder="Masukkan deskripsi sektor unggulan"
onChange={(val) => {
stateGrafik.create.form.description = val.currentTarget.value;
}}
/>
<Box>
<Text fw={"bold"} fz={"sm"}>Deskripsi Sektor Ungggulan</Text>
<CreateEditor
value={stateGrafik.create.form.description}
onChange={(val) => {
stateGrafik.create.form.description = val;
}}
/>
</Box>
<TextInput
label="Jumlah"
type="number"

View File

@@ -1,6 +1,6 @@
'use client'
import colors from '@/con/colors';
import { Box, Button, Paper, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core';
import { Box, Button, Paper, Stack, Table, TableTbody, TableTd, TableTh, TableThead, TableTr, Text, Title } from '@mantine/core';
import { IconDeviceImac, IconSearch } from '@tabler/icons-react';
import HeaderSearch from '../../_com/header';
import JudulList from '../../_com/judulList';
@@ -30,7 +30,7 @@ function SektorUnggulanDesa() {
function ListSektorUnggulanDesa({ search }: { search: string }) {
const router = useRouter();
const state = useProxy(grafikSektorUnggulan);
const [chartData, setChartData] = useState<{id: string; name: string; description: string | null; value: number | null}[]>([]);
const [chartData, setChartData] = useState<{ id: string; name: string; description: string | null; value: number | null }[]>([]);
const [mounted, setMounted] = useState(false); // untuk memastikan DOM sudah ready
const isTablet = useMediaQuery('(max-width: 1024px)')
const isMobile = useMediaQuery('(max-width: 768px)')
@@ -61,38 +61,41 @@ function ListSektorUnggulanDesa({ search }: { search: string }) {
}, [state.findMany.data]);
return (
<Box py={10}>
<Paper bg={colors['white-1']} p={'md'}>
<JudulList
title='List Sektor Unggulan Desa'
href='/admin/ekonomi/sektor-unggulan-desa/create'
/>
<Table striped withTableBorder withRowBorders>
<TableThead>
<TableTr>
<TableTh>Nama Sektor Unggulan</TableTh>
<TableTh>Deskripsi Sektor Unggulan</TableTh>
<TableTh>Detail</TableTh>
</TableTr>
</TableThead>
<TableTbody>
{filteredData.map((item) => (
<TableTr key={item.id}>
<TableTd>{item.name}</TableTd>
<TableTd>{item.description}</TableTd>
<TableTd>
<Button onClick={() => router.push(`/admin/ekonomi/sektor-unggulan-desa/${item.id}`)}>
<IconDeviceImac size={20} />
</Button>
</TableTd>
<Box>
<Stack gap={"xs"}>
<Paper bg={colors['white-1']} p={'md'}>
<JudulList
title='List Sektor Unggulan Desa'
href='/admin/ekonomi/sektor-unggulan-desa/create'
/>
<Table striped withTableBorder withRowBorders>
<TableThead>
<TableTr>
<TableTh>Nama Sektor Unggulan</TableTh>
<TableTh>Deskripsi Sektor Unggulan</TableTh>
<TableTh>Detail</TableTh>
</TableTr>
))}
</TableTbody>
</Table>
</Paper>
</TableThead>
<TableTbody>
{filteredData.map((item) => (
<TableTr key={item.id}>
<TableTd>{item.name}</TableTd>
<TableTd>
<Text truncate={"end"} fz={'sm'} lineClamp={1} dangerouslySetInnerHTML={{ __html: item.description || '' }}></Text>
</TableTd>
<TableTd>
<Button onClick={() => router.push(`/admin/ekonomi/sektor-unggulan-desa/${item.id}`)}>
<IconDeviceImac size={20} />
</Button>
</TableTd>
</TableTr>
))}
</TableTbody>
</Table>
</Paper>
{/* Chart */}
{!mounted && !chartData ? (
{/* Chart */}
{!mounted && !chartData ? (
<Box style={{ width: '100%', minWidth: 300, height: 400, minHeight: 300 }}>
<Paper bg={colors['white-1']} p={'md'}>
<Title pb={10} order={3}>Grafik Hasil Kepuasan Masyarakat</Title>
@@ -115,6 +118,7 @@ function ListSektorUnggulanDesa({ search }: { search: string }) {
</Paper>
</Box>
)}
</Stack>
</Box>
);
}

View File

@@ -1,192 +1,32 @@
'use client'
import colors from '@/con/colors';
import { Stack, Box, Paper, Text, ColorSwatch, Flex } from '@mantine/core';
import { Stack, Box, Paper, Text, ColorSwatch, Flex, Skeleton } from '@mantine/core';
import React from 'react';
import BackButton from '../../desa/layanan/_com/BackButto';
import { BarChart } from '@mantine/charts';
import { useProxy } from 'valtio/utils';
import grafikDemografiPekerjaan from '@/app/admin/(dashboard)/_state/ekonomi/demografi-pekerjaan';
import { useShallowEffect } from '@mantine/hooks';
const data = [
{
id: 1,
Pekerjaan: 'Guru',
laki: 2,
perempuan: 3
},
{
id: 2,
Pekerjaan: 'Belajar/Mahasiswa',
laki: 37,
perempuan: 38
},
{
id: 3,
Pekerjaan: 'Karyawan Bumdn',
laki: 1,
perempuan: 0
},
{
id: 4,
Pekerjaan: 'Buruh Tani/Perkebunan',
laki: 1,
perempuan: 0
},
{
id: 5,
Pekerjaan: 'Karyawan Swasta',
laki: 3,
perempuan: 17
},
{
id: 6,
Pekerjaan: 'Karyawan Honorer',
laki: 2,
perempuan: 1
},
{
id: 7,
Pekerjaan: 'Buruh Harian Lepas',
laki: 8,
perempuan: 5
},
{
id: 8,
Pekerjaan: 'Belum/Tidak Bekerja',
laki: 87,
perempuan: 44
},
{
id: 9,
Pekerjaan: ' Kepolisian RI (Polri)',
laki: 4,
perempuan: 0
},
{
id: 10,
Pekerjaan: 'Wiraswasta Mengurus Rumah Tangga',
laki: 1,
perempuan: 7
},
{
id: 11,
Pekerjaan: 'Dosen',
laki: 1,
perempuan: 1
},
{
id: 12,
Pekerjaan: 'Perangkat Desa',
laki: 17,
perempuan: 19
},
{
id: 13,
Pekerjaan: 'Nelayan',
laki: 3,
perempuan: 0
},
{
id: 14,
Pekerjaan: 'Penyuluh Pertanian',
laki: 33,
perempuan: 24
},
{
id: 15,
Pekerjaan: 'Tukang Las/Pandai Besi',
laki: 5,
perempuan: 0
},
{
id: 16,
Pekerjaan: 'Sopir/Driver',
laki: 10,
perempuan: 3
},
{
id: 17,
Pekerjaan: 'Teknisi/Listrik',
laki: 25,
perempuan: 0
},
{
id: 18,
Pekerjaan: 'Montir/Mekanik',
laki: 25,
perempuan: 0
},
{
id: 19,
Pekerjaan: 'Karyawan Hotel/Pariwisata',
laki: 2,
perempuan: 52
},
{
id: 20,
Pekerjaan: 'Pengrajin (Batik, Anyaman, Kayu)',
laki: 5,
perempuan: 25
},
{
id: 21,
Pekerjaan: 'Tukang Bangunan',
laki: 25,
perempuan: 5
},
{
id: 22,
Pekerjaan: 'Tukang Kayu/Furnitur',
laki: 25,
perempuan: 0
},
{
id: 23,
Pekerjaan: 'Penjahit',
laki: 2,
perempuan: 35
},
{
id: 24,
Pekerjaan: 'Pedagang Pasar',
laki: 25,
perempuan: 30
},
{
id: 25,
Pekerjaan: 'Warung Makan/Penjual Makanan',
laki: 15,
perempuan: 30
},
{
id: 26,
Pekerjaan: 'Satpam/Security',
laki: 20,
perempuan: 5
},
{
id: 27,
Pekerjaan: 'Pengusaha Kecil (UMKM)',
laki: 5,
perempuan: 20
},
{
id: 28,
Pekerjaan: 'Karyawan Restoran/Kafe',
laki: 5,
perempuan: 15
},
{
id: 29,
Pekerjaan: 'Freelancer',
laki: 20,
perempuan: 10
},
{
id: 30,
Pekerjaan: 'Fotografer',
laki: 25,
perempuan: 9
},
]
function Page() {
const state = useProxy(grafikDemografiPekerjaan)
const {
data,
} = state.findMany
useShallowEffect(() => {
state.findMany.load()
}, [])
if (!data) {
return (
<Stack py={10}>
<Skeleton h={500} />
</Stack>
)
}
return (
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
<Box px={{ base: 'md', md: 100 }}>
@@ -207,7 +47,13 @@ function Page() {
p={10}
mb={50}
h={400}
data={data}
w={150}
data={data.map((item) => ({
id: item.id,
Pekerjaan: item.pekerjaan,
laki: item.lakiLaki,
perempuan: item.perempuan,
}))}
dataKey="Pekerjaan"
series={[
{ name: 'laki', color: '#5082EE' },

View File

@@ -1,23 +1,33 @@
'use client'
import colors from '@/con/colors';
import { Stack, Box, Text, Paper } from '@mantine/core';
import { Stack, Box, Text, Paper, Skeleton } from '@mantine/core';
import React from 'react';
import BackButton from '../../desa/layanan/_com/BackButto';
import { BarChart } from '@mantine/charts';
import { useProxy } from 'valtio/utils';
import grafikSektorUnggulan from '@/app/admin/(dashboard)/_state/ekonomi/sektor-unggulan-desa';
import { useShallowEffect } from '@mantine/hooks';
const data = [
{
id: 1,
sektor: 'Sektor Pertanian',
Ton: 20
},
{
id: 2,
sektor: 'Sektor Peternakan',
Ton: 5
},
]
function Page() {
const state = useProxy(grafikSektorUnggulan)
const {
data,
loading,
} = state.findMany
useShallowEffect(() => {
state.findMany.load()
}, [])
if (loading || !data) {
return (
<Stack py={10}>
<Skeleton h={500} />
</Stack>
)
}
return (
<Stack pos={"relative"} bg={colors.Bg} py={"xl"} gap={"22"}>
<Box px={{ base: 'md', md: 100 }}>
@@ -31,28 +41,24 @@ function Page() {
</Box>
<Box px={{ base: "md", md: 100 }}>
<Stack gap={'lg'} justify='center'>
<Paper p={'xl'}>
<Text fw={'bold'} fz={'h4'}>Jumlah Penduduk Miskin Per Tahun</Text>
<Text fz={'h4'} ta={'justify'}>
Pertanian di Darmasaba berfokus pada padi, sayuran, dan hortikultura yang dikembangkan dengan metode pertanian
organik serta sistem irigasi tradisional yang efisien. Keberlanjutan dalam pertanian juga didukung dengan pemanfaatan
teknologi modern untuk meningkatkan produktivitas hasil panen.
</Text>
</Paper>
<Paper p={'xl'}>
<Text fw={'bold'} fz={'h4'}>Sektor Peternakan</Text>
<Text fz={'h4'} ta={'justify'}>
Di bidang peternakan, Desa Darmasaba memiliki potensi besar dalam pengembangan sapi, ayam, dan babi. Sistem
peternakan yang diterapkan mengutamakan pengelolaan pakan alami dan perawatan hewan yang sehat, sehingga
menghasilkan produk ternak berkualitas tinggi.
</Text>
</Paper>
{data.map((v, k) => {
return (
<Paper p={'xl'} key={k}>
<Text fw={'bold'} fz={'h4'}>{v.name}</Text>
<Text fz={'h4'} ta={'justify'} dangerouslySetInnerHTML={{ __html: v.description || '' }} />
</Paper>
)
})}
<Paper p={'xl'}>
<Text pb={10} fw={'bold'} fz={'h4'}>Statistik Sektor Unggulan Darmasaba</Text>
<BarChart
p={10}
h={300}
data={data}
data={data.map((item) => ({
id: item.id,
sektor: item.name,
Ton: item.value,
}))}
dataKey="sektor"
series={[
{ name: 'Ton', color: colors['blue-button'] },