fix inputan edit menu: desa, ekonomi, inovasi, keamanan, kesehatan, landing-page, & lingkungan
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
'use client'
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
import PendapatanAsliDesa from '@/app/admin/(dashboard)/_state/ekonomi/PADesa';
|
||||
import colors from '@/con/colors';
|
||||
import {
|
||||
@@ -29,13 +29,13 @@ function EditAPBDesa() {
|
||||
const params = useParams();
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
tahun: apbState.update.form.tahun || '',
|
||||
pendapatanIds: apbState.update.form.pendapatanIds || [],
|
||||
belanjaIds: apbState.update.form.belanjaIds || [],
|
||||
pembiayaanIds: apbState.update.form.pembiayaanIds || [],
|
||||
tahun: '',
|
||||
pendapatanIds: [] as string[],
|
||||
belanjaIds: [] as string[],
|
||||
pembiayaanIds: [] as string[],
|
||||
});
|
||||
|
||||
// Load APB desa by id
|
||||
// Load APB desa by id → hanya update formData, bukan global state
|
||||
useEffect(() => {
|
||||
const loadAPBdesa = async () => {
|
||||
const id = params?.id as string;
|
||||
@@ -45,7 +45,7 @@ function EditAPBDesa() {
|
||||
const data = await apbState.update.load(id);
|
||||
if (data) {
|
||||
setFormData({
|
||||
tahun: data.tahun || 0,
|
||||
tahun: String(data.tahun || ''),
|
||||
pendapatanIds: data.pendapatan?.map((p: any) => p.id) || [],
|
||||
belanjaIds: data.belanja?.map((b: any) => b.id) || [],
|
||||
pembiayaanIds: data.pembiayaan?.map((p: any) => p.id) || [],
|
||||
@@ -60,8 +60,13 @@ function EditAPBDesa() {
|
||||
loadAPBdesa();
|
||||
}, [params?.id]);
|
||||
|
||||
const handleChange = (field: keyof typeof formData, value: any) => {
|
||||
setFormData(prev => ({ ...prev, [field]: value }));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
// update global state cuma pas submit
|
||||
apbState.update.form = {
|
||||
...apbState.update.form,
|
||||
tahun: Number(formData.tahun),
|
||||
@@ -111,10 +116,8 @@ function EditAPBDesa() {
|
||||
{/* Tahun */}
|
||||
<TextInput
|
||||
type="number"
|
||||
defaultValue={formData.tahun}
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, tahun: e.target.value })
|
||||
}
|
||||
value={formData.tahun}
|
||||
onChange={(e) => handleChange("tahun", e.target.value)}
|
||||
label={<Text fz="sm" fw="bold">Tahun</Text>}
|
||||
placeholder="Masukkan tahun anggaran"
|
||||
required
|
||||
@@ -123,23 +126,17 @@ function EditAPBDesa() {
|
||||
{/* Selects */}
|
||||
<SelectPendapatan
|
||||
selectedIds={formData.pendapatanIds}
|
||||
onSelectionChange={(ids) =>
|
||||
setFormData({ ...formData, pendapatanIds: ids })
|
||||
}
|
||||
onSelectionChange={(ids) => handleChange("pendapatanIds", ids)}
|
||||
/>
|
||||
|
||||
<SelectBelanja
|
||||
selectedIds={formData.belanjaIds}
|
||||
onSelectionChange={(ids) =>
|
||||
setFormData({ ...formData, belanjaIds: ids })
|
||||
}
|
||||
onSelectionChange={(ids) => handleChange("belanjaIds", ids)}
|
||||
/>
|
||||
|
||||
<SelectPembiayaan
|
||||
selectedIds={formData.pembiayaanIds}
|
||||
onSelectionChange={(ids) =>
|
||||
setFormData({ ...formData, pembiayaanIds: ids })
|
||||
}
|
||||
onSelectionChange={(ids) => handleChange("pembiayaanIds", ids)}
|
||||
/>
|
||||
|
||||
{/* Save Button */}
|
||||
@@ -164,7 +161,13 @@ function EditAPBDesa() {
|
||||
|
||||
/* --- Sub Components --- */
|
||||
|
||||
function SelectPendapatan({ selectedIds, onSelectionChange }: { selectedIds: string[]; onSelectionChange: (ids: string[]) => void }) {
|
||||
function SelectPendapatan({
|
||||
selectedIds,
|
||||
onSelectionChange,
|
||||
}: {
|
||||
selectedIds: string[];
|
||||
onSelectionChange: (ids: string[]) => void;
|
||||
}) {
|
||||
const pendapatanState = useProxy(PendapatanAsliDesa.pendapatan);
|
||||
|
||||
useShallowEffect(() => {
|
||||
@@ -192,7 +195,13 @@ function EditAPBDesa() {
|
||||
);
|
||||
}
|
||||
|
||||
function SelectBelanja({ selectedIds, onSelectionChange }: { selectedIds: string[]; onSelectionChange: (ids: string[]) => void }) {
|
||||
function SelectBelanja({
|
||||
selectedIds,
|
||||
onSelectionChange,
|
||||
}: {
|
||||
selectedIds: string[];
|
||||
onSelectionChange: (ids: string[]) => void;
|
||||
}) {
|
||||
const belanjaState = useProxy(PendapatanAsliDesa.belanja);
|
||||
|
||||
useShallowEffect(() => {
|
||||
@@ -220,7 +229,13 @@ function EditAPBDesa() {
|
||||
);
|
||||
}
|
||||
|
||||
function SelectPembiayaan({ selectedIds, onSelectionChange }: { selectedIds: string[]; onSelectionChange: (ids: string[]) => void }) {
|
||||
function SelectPembiayaan({
|
||||
selectedIds,
|
||||
onSelectionChange,
|
||||
}: {
|
||||
selectedIds: string[];
|
||||
onSelectionChange: (ids: string[]) => void;
|
||||
}) {
|
||||
const pembiayaanState = useProxy(PendapatanAsliDesa.pembiayaan);
|
||||
|
||||
useShallowEffect(() => {
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
/* eslint-disable react-hooks/exhaustive-deps */
|
||||
'use client'
|
||||
|
||||
import PendapatanAsliDesa from '@/app/admin/(dashboard)/_state/ekonomi/PADesa';
|
||||
import colors from '@/con/colors';
|
||||
import {
|
||||
@@ -24,12 +25,16 @@ function EditBelanja() {
|
||||
const params = useParams();
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
name: belanjaState.update.form.name || '',
|
||||
value: belanjaState.update.form.value || '',
|
||||
name: '',
|
||||
value: '',
|
||||
});
|
||||
|
||||
// format angka ke rupiah
|
||||
const formatRupiah = (value: number | string) => {
|
||||
const number = typeof value === 'number' ? value : Number(value.replace(/\D/g, ''));
|
||||
const number =
|
||||
typeof value === 'number'
|
||||
? value
|
||||
: Number(value.replace(/\D/g, '')) || 0;
|
||||
return new Intl.NumberFormat('id-ID', {
|
||||
style: 'currency',
|
||||
currency: 'IDR',
|
||||
@@ -37,8 +42,9 @@ function EditBelanja() {
|
||||
}).format(number);
|
||||
};
|
||||
|
||||
// buang semua simbol jadi angka murni
|
||||
const unformatRupiah = (value: string) => {
|
||||
return Number(value.replace(/\D/g, ''));
|
||||
return Number(value.replace(/\D/g, '')) || 0;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -51,7 +57,7 @@ function EditBelanja() {
|
||||
if (data) {
|
||||
setFormData({
|
||||
name: data.name || '',
|
||||
value: data.value || '',
|
||||
value: String(data.value || ''),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -69,7 +75,7 @@ function EditBelanja() {
|
||||
...belanjaState.update.form,
|
||||
name: formData.name,
|
||||
value: Number(formData.value),
|
||||
}
|
||||
};
|
||||
|
||||
await belanjaState.update.update();
|
||||
toast.success("Jenis Belanja berhasil diperbarui!");
|
||||
@@ -78,7 +84,7 @@ function EditBelanja() {
|
||||
console.error("Error updating jenis belanja:", error);
|
||||
toast.error("Terjadi kesalahan saat memperbarui jenis belanja");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box px={{ base: 'sm', md: 'lg' }} py="md">
|
||||
@@ -112,19 +118,21 @@ function EditBelanja() {
|
||||
<TextInput
|
||||
label="Nama Jenis Belanja"
|
||||
placeholder="Masukkan nama jenis belanja"
|
||||
defaultValue={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
value={formData.name}
|
||||
onChange={(e) =>
|
||||
setFormData({ ...formData, name: e.target.value })
|
||||
}
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Nilai"
|
||||
placeholder="Masukkan nilai"
|
||||
defaultValue={formatRupiah(formData.value)}
|
||||
value={formData.value ? formatRupiah(formData.value) : ''}
|
||||
onChange={(e) => {
|
||||
const raw = e.currentTarget.value;
|
||||
const cleanValue = unformatRupiah(raw);
|
||||
setFormData({ ...formData, value: cleanValue });
|
||||
setFormData({ ...formData, value: String(cleanValue) });
|
||||
}}
|
||||
required
|
||||
/>
|
||||
|
||||
@@ -24,12 +24,15 @@ function EditPembiayaan() {
|
||||
const params = useParams();
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
name: pembiayaanState.update.form.name || '',
|
||||
value: pembiayaanState.update.form.value || '',
|
||||
name: '',
|
||||
value: '',
|
||||
});
|
||||
|
||||
const formatRupiah = (value: number | string) => {
|
||||
const number = typeof value === 'number' ? value : Number(value.toString().replace(/\D/g, ''));
|
||||
const number =
|
||||
typeof value === 'number'
|
||||
? value
|
||||
: Number(value.toString().replace(/\D/g, '')) || 0;
|
||||
return new Intl.NumberFormat('id-ID', {
|
||||
style: 'currency',
|
||||
currency: 'IDR',
|
||||
@@ -38,7 +41,7 @@ function EditPembiayaan() {
|
||||
};
|
||||
|
||||
const unformatRupiah = (value: string) => {
|
||||
return Number(value.replace(/\D/g, ''));
|
||||
return Number(value.replace(/\D/g, '')) || 0;
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
@@ -51,7 +54,7 @@ function EditPembiayaan() {
|
||||
if (data) {
|
||||
setFormData({
|
||||
name: data.name || '',
|
||||
value: data.value || '',
|
||||
value: String(data.value || ''),
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -68,7 +71,7 @@ function EditPembiayaan() {
|
||||
pembiayaanState.update.form = {
|
||||
...pembiayaanState.update.form,
|
||||
name: formData.name,
|
||||
value: Number(formData.value),
|
||||
value: unformatRupiah(formData.value),
|
||||
};
|
||||
|
||||
await pembiayaanState.update.update();
|
||||
@@ -82,7 +85,7 @@ function EditPembiayaan() {
|
||||
|
||||
return (
|
||||
<Box px={{ base: 'sm', md: 'lg' }} py="md">
|
||||
{/* Header dengan Back Button */}
|
||||
{/* Header */}
|
||||
<Group mb="md">
|
||||
<Tooltip label="Kembali ke halaman sebelumnya" withArrow>
|
||||
<Button
|
||||
@@ -112,19 +115,21 @@ function EditPembiayaan() {
|
||||
<TextInput
|
||||
label="Nama Jenis Pembiayaan"
|
||||
placeholder="Masukkan nama jenis pembiayaan"
|
||||
defaultValue={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
value={formData.name}
|
||||
onChange={(e) =>
|
||||
setFormData((prev) => ({ ...prev, name: e.target.value }))
|
||||
}
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Nilai"
|
||||
placeholder="Masukkan nilai"
|
||||
defaultValue={formatRupiah(formData.value)}
|
||||
value={formData.value ? formatRupiah(formData.value) : ''}
|
||||
onChange={(e) => {
|
||||
const raw = e.currentTarget.value;
|
||||
const cleanValue = unformatRupiah(raw);
|
||||
setFormData({ ...formData, value: cleanValue });
|
||||
setFormData((prev) => ({ ...prev, value: String(cleanValue) }));
|
||||
}}
|
||||
required
|
||||
/>
|
||||
|
||||
@@ -24,12 +24,16 @@ function EditPendapatan() {
|
||||
const params = useParams();
|
||||
|
||||
const [formData, setFormData] = useState({
|
||||
name: pendapatanState.update.form.name || '',
|
||||
value: pendapatanState.update.form.value || '',
|
||||
name: '',
|
||||
value: '',
|
||||
});
|
||||
|
||||
// helper format
|
||||
const formatRupiah = (value: number | string) => {
|
||||
const number = typeof value === 'number' ? value : Number(value.toString().replace(/\D/g, ''));
|
||||
const number = typeof value === 'number'
|
||||
? value
|
||||
: Number(value.toString().replace(/\D/g, ''));
|
||||
|
||||
return new Intl.NumberFormat('id-ID', {
|
||||
style: 'currency',
|
||||
currency: 'IDR',
|
||||
@@ -39,6 +43,7 @@ function EditPendapatan() {
|
||||
|
||||
const unformatRupiah = (value: string) => Number(value.replace(/\D/g, ''));
|
||||
|
||||
// load data once
|
||||
useEffect(() => {
|
||||
const id = params?.id as string;
|
||||
if (!id) return;
|
||||
@@ -48,8 +53,8 @@ function EditPendapatan() {
|
||||
const data = await pendapatanState.update.load(id);
|
||||
if (data) {
|
||||
setFormData({
|
||||
name: data.name || '',
|
||||
value: data.value || '',
|
||||
name: data.name ?? '',
|
||||
value: data.value?.toString() ?? '',
|
||||
});
|
||||
}
|
||||
} catch (error) {
|
||||
@@ -61,6 +66,13 @@ function EditPendapatan() {
|
||||
loadPendapatan();
|
||||
}, [params?.id]);
|
||||
|
||||
const handleChange = (field: string, value: string) => {
|
||||
setFormData((prev) => ({
|
||||
...prev,
|
||||
[field]: value,
|
||||
}));
|
||||
};
|
||||
|
||||
const handleSubmit = async () => {
|
||||
try {
|
||||
pendapatanState.update.form = {
|
||||
@@ -110,19 +122,19 @@ function EditPendapatan() {
|
||||
<TextInput
|
||||
label="Nama Jenis Pendapatan"
|
||||
placeholder="Masukkan nama jenis pendapatan"
|
||||
defaultValue={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
value={formData.name}
|
||||
onChange={(e) => handleChange('name', e.target.value)}
|
||||
required
|
||||
/>
|
||||
|
||||
<TextInput
|
||||
label="Nilai"
|
||||
placeholder="Masukkan nilai"
|
||||
defaultValue={formatRupiah(formData.value)}
|
||||
value={formData.value ? formatRupiah(formData.value) : ''}
|
||||
onChange={(e) => {
|
||||
const raw = e.currentTarget.value;
|
||||
const cleanValue = unformatRupiah(raw);
|
||||
setFormData({ ...formData, value: cleanValue });
|
||||
const cleanValue = unformatRupiah(raw).toString();
|
||||
handleChange('value', cleanValue);
|
||||
}}
|
||||
required
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user