Fix QC Kak Inno Admin, Fix QC Keano UI User, Fix QC Pak jun tabel apbdes

This commit is contained in:
2025-11-12 17:42:31 +08:00
parent 417a8937f5
commit 9622eb5a9a
354 changed files with 11444 additions and 4012 deletions

View File

@@ -2,10 +2,11 @@
'use client';
import grafikNganggur from '@/app/admin/(dashboard)/_state/ekonomi/usia-kerja-nganggur';
import colors from '@/con/colors';
import { Box, Button, Group, Paper, Stack, TextInput, Title } from '@mantine/core';
import { Box, Button, Group, Loader, Paper, Stack, TextInput, Title } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react';
import { useParams, useRouter } from 'next/navigation';
import { useEffect, useState } from 'react';
import { toast } from 'react-toastify';
import { useProxy } from 'valtio/utils';
function EditGrafikBerdasarkanPendidikan() {
@@ -13,6 +14,7 @@ function EditGrafikBerdasarkanPendidikan() {
const params = useParams() as { id: string };
const stategrafik = useProxy(grafikNganggur.grafikBerdasarkanPendidikan);
const id = params.id;
const [isSubmitting, setIsSubmitting] = useState(false);
// state lokal untuk form
const [formData, setFormData] = useState({
@@ -23,6 +25,14 @@ function EditGrafikBerdasarkanPendidikan() {
S1: '',
});
const [originalData, setOriginalData] = useState({
SD: '',
SMP: '',
SMA: '',
D3: '',
S1: '',
});
useEffect(() => {
if (id) {
stategrafik.findUnique.load(id).then(() => {
@@ -35,26 +45,51 @@ function EditGrafikBerdasarkanPendidikan() {
D3: data.D3 || '',
S1: data.S1 || '',
});
setOriginalData({
SD: data.SD || '',
SMP: data.SMP || '',
SMA: data.SMA || '',
D3: data.D3 || '',
S1: data.S1 || '',
});
}
});
}
}, [id]);
const handleChange = (field: keyof typeof formData) =>
(e: React.ChangeEvent<HTMLInputElement>) => {
setFormData((prev) => ({
...prev,
[field]: e.currentTarget.value,
}));
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.currentTarget;
setFormData((prev) => ({ ...prev, [name]: value }));
};
const handleResetForm = () => {
setFormData({
SD: originalData.SD,
SMP: originalData.SMP,
SMA: originalData.SMA,
D3: originalData.D3,
S1: originalData.S1,
});
toast.info("Form dikembalikan ke data awal");
};
const handleSubmit = async () => {
stategrafik.update.id = id;
stategrafik.update.form = { ...formData }; // update global state pas submit aja
await stategrafik.update.submit();
router.push(
'/admin/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/pengangguran_berdasarkan_pendidikan'
);
try {
setIsSubmitting(true);
stategrafik.update.id = id;
stategrafik.update.form = { ...formData }; // update global state pas submit aja
await stategrafik.update.submit();
router.push(
'/admin/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/pengangguran_berdasarkan_pendidikan'
);
} catch (error) {
console.error(error);
toast.error('Terjadi kesalahan saat memperbarui data grafik');
} finally {
setIsSubmitting(false);
}
};
return (
@@ -83,42 +118,58 @@ function EditGrafikBerdasarkanPendidikan() {
>
<Stack gap="md">
<TextInput
name="SD"
label="SD"
type="number"
placeholder="Masukkan jumlah"
value={formData.SD}
onChange={handleChange('SD')}
onChange={handleChange}
/>
<TextInput
name="SMP"
label="SMP"
type="number"
placeholder="Masukkan jumlah"
value={formData.SMP}
onChange={handleChange('SMP')}
onChange={handleChange}
/>
<TextInput
name="SMA"
label="SMA"
type="number"
placeholder="Masukkan jumlah"
value={formData.SMA}
onChange={handleChange('SMA')}
onChange={handleChange}
/>
<TextInput
name="D3"
label="D3"
type="number"
placeholder="Masukkan jumlah"
value={formData.D3}
onChange={handleChange('D3')}
onChange={handleChange}
/>
<TextInput
name="S1"
label="S1"
type="number"
placeholder="Masukkan jumlah"
value={formData.S1}
onChange={handleChange('S1')}
onChange={handleChange}
/>
<Group justify="right">
<Button
variant="outline"
color="gray"
radius="md"
size="md"
onClick={handleResetForm}
>
Batal
</Button>
{/* Tombol Simpan */}
<Button
onClick={handleSubmit}
radius="md"
@@ -129,7 +180,7 @@ function EditGrafikBerdasarkanPendidikan() {
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
}}
>
Simpan
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
</Button>
</Group>
</Stack>

View File

@@ -3,16 +3,18 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
import grafikNganggur from '@/app/admin/(dashboard)/_state/ekonomi/usia-kerja-nganggur';
import colors from '@/con/colors';
import { Box, Button, Group, Paper, Stack, TextInput, Title } from '@mantine/core';
import { Box, Button, Loader, Group, Paper, Stack, TextInput, Title } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { toast } from 'react-toastify';
import { useProxy } from 'valtio/utils';
function CreateGrafikBerdasarkanPendidikan() {
const router = useRouter();
const stategrafik = useProxy(grafikNganggur.grafikBerdasarkanPendidikan);
const [donutData, setDonutData] = useState<any[]>([]);
const [isSubmitting, setIsSubmitting] = useState(false);
const resetForm = () => {
stategrafik.create.form = {
@@ -26,18 +28,26 @@ function CreateGrafikBerdasarkanPendidikan() {
};
const handleSubmit = async () => {
const id = await stategrafik.create.create();
if (id) {
const idStr = String(id);
await stategrafik.findUnique.load(idStr);
if (stategrafik.findUnique.data) {
setDonutData([stategrafik.findUnique.data]);
try {
setIsSubmitting(true);
const id = await stategrafik.create.create();
if (id) {
const idStr = String(id);
await stategrafik.findUnique.load(idStr);
if (stategrafik.findUnique.data) {
setDonutData([stategrafik.findUnique.data]);
}
}
resetForm();
router.push(
'/admin/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/pengangguran_berdasarkan_pendidikan'
);
} catch (error) {
console.error(error);
toast.error('Terjadi kesalahan saat menambahkan data grafik');
} finally {
setIsSubmitting(false);
}
resetForm();
router.push(
'/admin/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/pengangguran_berdasarkan_pendidikan'
);
};
return (
@@ -64,7 +74,7 @@ function CreateGrafikBerdasarkanPendidikan() {
label="SD"
type="number"
placeholder="Masukkan jumlah"
defaultValue={stategrafik.create.form.SD}
value={stategrafik.create.form.SD}
onChange={(val) => (stategrafik.create.form.SD = val.currentTarget.value)}
required
/>
@@ -72,7 +82,7 @@ function CreateGrafikBerdasarkanPendidikan() {
label="SMP"
type="number"
placeholder="Masukkan jumlah"
defaultValue={stategrafik.create.form.SMP}
value={stategrafik.create.form.SMP}
onChange={(val) => (stategrafik.create.form.SMP = val.currentTarget.value)}
required
/>
@@ -80,7 +90,7 @@ function CreateGrafikBerdasarkanPendidikan() {
label="SMA"
type="number"
placeholder="Masukkan jumlah"
defaultValue={stategrafik.create.form.SMA}
value={stategrafik.create.form.SMA}
onChange={(val) => (stategrafik.create.form.SMA = val.currentTarget.value)}
required
/>
@@ -88,7 +98,7 @@ function CreateGrafikBerdasarkanPendidikan() {
label="D3"
type="number"
placeholder="Masukkan jumlah"
defaultValue={stategrafik.create.form.D3}
value={stategrafik.create.form.D3}
onChange={(val) => (stategrafik.create.form.D3 = val.currentTarget.value)}
required
/>
@@ -96,12 +106,23 @@ function CreateGrafikBerdasarkanPendidikan() {
label="S1"
type="number"
placeholder="Masukkan jumlah"
defaultValue={stategrafik.create.form.S1}
value={stategrafik.create.form.S1}
onChange={(val) => (stategrafik.create.form.S1 = val.currentTarget.value)}
required
/>
<Group justify="right" mt="md">
<Button
variant="outline"
color="gray"
radius="md"
size="md"
onClick={resetForm}
>
Reset
</Button>
{/* Tombol Simpan */}
<Button
onClick={handleSubmit}
radius="md"
@@ -112,7 +133,7 @@ function CreateGrafikBerdasarkanPendidikan() {
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
}}
>
Simpan
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
</Button>
</Group>
</Stack>

View File

@@ -217,20 +217,22 @@ function ListGrafikBerdasarkanPendidikan({ search }: { search: string }) {
<Title order={3} pb={10}>
Grafik Pengangguran Berdasarkan Pendidikan
</Title>
{donutData.length > 0 ? (
<DonutChart
data={donutData}
withLabels
withTooltip
tooltipDataSource="segment"
size={260}
thickness={40}
/>
) : (
<Text color="dimmed">
Belum ada data untuk ditampilkan dalam grafik
</Text>
)}
<Center>
{donutData.length > 0 ? (
<DonutChart
data={donutData}
withLabels
withTooltip
tooltipDataSource="segment"
size={260}
thickness={40}
/>
) : (
<Text color="dimmed">
Belum ada data untuk ditampilkan dalam grafik
</Text>
)}
</Center>
</Stack>
</Paper>

View File

@@ -6,6 +6,7 @@ import {
Box,
Button,
Group,
Loader,
Paper,
Stack,
TextInput,
@@ -25,6 +26,8 @@ function EditGrafikBerdasarkanUsiaKerjaYangMenganggur() {
);
const id = params.id;
const [isSubmitting, setIsSubmitting] = useState(false);
// ✅ state lokal, controlled
const [formData, setFormData] = useState({
usia18_25: '',
@@ -33,6 +36,13 @@ function EditGrafikBerdasarkanUsiaKerjaYangMenganggur() {
usia46_keatas: '',
});
const [originalData, setOriginalData] = useState({
usia18_25: '',
usia26_35: '',
usia36_45: '',
usia46_keatas: '',
});
// load data dari global state -> masukin ke local state
useEffect(() => {
if (id) {
@@ -45,6 +55,13 @@ function EditGrafikBerdasarkanUsiaKerjaYangMenganggur() {
usia36_45: data.usia36_45 || '',
usia46_keatas: data.usia46_keatas || '',
});
setOriginalData({
usia18_25: data.usia18_25 || '',
usia26_35: data.usia26_35 || '',
usia36_45: data.usia36_45 || '',
usia46_keatas: data.usia46_keatas || '',
});
}
});
}
@@ -57,8 +74,19 @@ function EditGrafikBerdasarkanUsiaKerjaYangMenganggur() {
}));
};
const handleResetForm = () => {
setFormData({
usia18_25: originalData.usia18_25,
usia26_35: originalData.usia26_35,
usia36_45: originalData.usia36_45,
usia46_keatas: originalData.usia46_keatas,
});
toast.info('Form dikembalikan ke data awal');
};
const handleSubmit = async () => {
try {
setIsSubmitting(true);
// ✅ baru update global state pas submit
stategrafik.update.id = id;
stategrafik.update.form = { ...formData };
@@ -72,6 +100,8 @@ function EditGrafikBerdasarkanUsiaKerjaYangMenganggur() {
} catch (error) {
console.error(error);
toast.error('Terjadi kesalahan saat memperbarui data grafik');
} finally {
setIsSubmitting(false);
}
};
@@ -134,6 +164,17 @@ function EditGrafikBerdasarkanUsiaKerjaYangMenganggur() {
/>
<Group justify="right">
<Button
variant="outline"
color="gray"
radius="md"
size="md"
onClick={handleResetForm}
>
Batal
</Button>
{/* Tombol Simpan */}
<Button
onClick={handleSubmit}
radius="md"
@@ -144,7 +185,7 @@ function EditGrafikBerdasarkanUsiaKerjaYangMenganggur() {
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
}}
>
Simpan
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
</Button>
</Group>
</Stack>

View File

@@ -4,16 +4,18 @@
import grafikNganggur from '@/app/admin/(dashboard)/_state/ekonomi/usia-kerja-nganggur';
import colors from '@/con/colors';
import { Box, Button, Group, Paper, Stack, TextInput, Title } from '@mantine/core';
import { Box, Button, Group, Loader, Paper, Stack, TextInput, Title } from '@mantine/core';
import { IconArrowBack } from '@tabler/icons-react';
import { useRouter } from 'next/navigation';
import { useState } from 'react';
import { toast } from 'react-toastify';
import { useProxy } from 'valtio/utils';
function CreateGrafikBerdasarkanUsiaKerjaYangMenganggur() {
const router = useRouter();
const stategrafik = useProxy(grafikNganggur.grafikBerdasarkanUsiaKerjaNganggur);
const [donutData, setDonutData] = useState<any[]>([]);
const [isSubmitting, setIsSubmitting] = useState(false);
const resetForm = () => {
stategrafik.create.form = {
@@ -26,16 +28,24 @@ function CreateGrafikBerdasarkanUsiaKerjaYangMenganggur() {
};
const handleSubmit = async () => {
const id = await stategrafik.create.create();
if (id) {
const idStr = String(id);
await stategrafik.findUnique.load(idStr);
if (stategrafik.findUnique.data) {
setDonutData([stategrafik.findUnique.data]);
try {
setIsSubmitting(true);
const id = await stategrafik.create.create();
if (id) {
const idStr = String(id);
await stategrafik.findUnique.load(idStr);
if (stategrafik.findUnique.data) {
setDonutData([stategrafik.findUnique.data]);
}
}
resetForm();
router.push('/admin/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/pengangguran_berdasarkan_usia');
} catch (error) {
console.error('Error creating:', error);
toast.error('Terjadi kesalahan saat membuat data');
} finally {
setIsSubmitting(false);
}
resetForm();
router.push('/admin/ekonomi/jumlah-penduduk-usia-kerja-yang-menganggur/pengangguran_berdasarkan_usia');
};
return (
@@ -64,7 +74,7 @@ function CreateGrafikBerdasarkanUsiaKerjaYangMenganggur() {
label="Usia 18 - 25"
type="number"
placeholder="Masukkan jumlah"
defaultValue={stategrafik.create.form.usia18_25}
value={stategrafik.create.form.usia18_25}
onChange={(val) => (stategrafik.create.form.usia18_25 = val.currentTarget.value)}
required
/>
@@ -72,7 +82,7 @@ function CreateGrafikBerdasarkanUsiaKerjaYangMenganggur() {
label="Usia 26 - 35"
type="number"
placeholder="Masukkan jumlah"
defaultValue={stategrafik.create.form.usia26_35}
value={stategrafik.create.form.usia26_35}
onChange={(val) => (stategrafik.create.form.usia26_35 = val.currentTarget.value)}
required
/>
@@ -80,7 +90,7 @@ function CreateGrafikBerdasarkanUsiaKerjaYangMenganggur() {
label="Usia 36 - 45"
type="number"
placeholder="Masukkan jumlah"
defaultValue={stategrafik.create.form.usia36_45}
value={stategrafik.create.form.usia36_45}
onChange={(val) => (stategrafik.create.form.usia36_45 = val.currentTarget.value)}
required
/>
@@ -88,13 +98,24 @@ function CreateGrafikBerdasarkanUsiaKerjaYangMenganggur() {
label="Usia 46 +"
type="number"
placeholder="Masukkan jumlah"
defaultValue={stategrafik.create.form.usia46_keatas}
value={stategrafik.create.form.usia46_keatas}
onChange={(val) => (stategrafik.create.form.usia46_keatas = val.currentTarget.value)}
required
/>
{/* Submit Button */}
<Group justify="right">
<Button
variant="outline"
color="gray"
radius="md"
size="md"
onClick={resetForm}
>
Reset
</Button>
{/* Tombol Simpan */}
<Button
onClick={handleSubmit}
radius="md"
@@ -105,7 +126,7 @@ function CreateGrafikBerdasarkanUsiaKerjaYangMenganggur() {
boxShadow: '0 4px 15px rgba(79, 172, 254, 0.4)',
}}
>
Simpan
{isSubmitting ? <Loader size="sm" color="white" /> : 'Simpan'}
</Button>
</Group>
</Stack>