UI & API Menu Ekonomi, SubMenu PADesa : Tabs Pendapatan, Pembiayaan, dan Belanja

This commit is contained in:
2025-07-11 17:51:07 +08:00
parent cb52701f47
commit 4baffe95f3
24 changed files with 1438 additions and 330 deletions

View File

@@ -19,6 +19,19 @@ function EditPendapatan() {
value: pendapatanState.update.form.value || '',
});
const formatRupiah = (value: number | string) => {
const number = typeof value === 'number' ? value : Number(value.replace(/\D/g, ''));
return new Intl.NumberFormat('id-ID', {
style: 'currency',
currency: 'IDR',
minimumFractionDigits: 0,
}).format(number);
};
const unformatRupiah = (value: string) => {
return Number(value.replace(/\D/g, ''));
};
useEffect(() => {
const loadPendapatan = async () => {
const id = params?.id as string;
@@ -80,9 +93,11 @@ function EditPendapatan() {
<TextInput
label={<Text fw={"bold"} fz={"sm"}>Nilai</Text>}
placeholder='Masukkan nilai'
value={formData.value}
value={formatRupiah(formData.value)}
onChange={(val) => {
setFormData({ ...formData, value: val.target.value });
const raw = val.currentTarget.value;
const cleanValue = unformatRupiah(raw);
setFormData({ ...formData, value: cleanValue });
}}
/>
<Group>

View File

@@ -10,6 +10,19 @@ function CreatePendapatan() {
const pendapatanState = useProxy(PendapatanAsliDesa.pendapatan)
const router = useRouter()
const formatRupiah = (value: number | string) => {
const number = typeof value === 'number' ? value : Number(value.replace(/\D/g, ''));
return new Intl.NumberFormat('id-ID', {
style: 'currency',
currency: 'IDR',
minimumFractionDigits: 0,
}).format(number);
};
const unformatRupiah = (value: string) => {
return Number(value.replace(/\D/g, ''));
};
const resetForm = () => {
pendapatanState.create.form = {
name: "",
@@ -42,10 +55,12 @@ function CreatePendapatan() {
placeholder='Masukkan nama jenis pendapatan'
/>
<TextInput
type='number'
value={pendapatanState.create.form.value}
type='text'
value={formatRupiah(pendapatanState.create.form.value)}
onChange={(val) => {
pendapatanState.create.form.value = Number(val.target.value);
const raw = val.currentTarget.value;
const cleanValue = unformatRupiah(raw);
pendapatanState.create.form.value = cleanValue;
}}
label={<Text fw={"bold"} fz={"sm"}>Nilai</Text>}
placeholder='Masukkan nilai'

View File

@@ -34,6 +34,14 @@ function ListPendapatan({ search }: { search: string }) {
const [modalHapus, setModalHapus] = useState(false)
const [selectedId, setSelectedId] = useState<string | null>(null)
const formatRupiah = (value: number) => {
return new Intl.NumberFormat('id-ID', {
style: 'currency',
currency: 'IDR',
minimumFractionDigits: 0,
}).format(value);
};
const handleDelete = () => {
if (selectedId) {
@@ -83,7 +91,7 @@ function ListPendapatan({ search }: { search: string }) {
{filteredData.map((item) => (
<TableTr key={item.id}>
<TableTd>{item.name}</TableTd>
<TableTd>{item.value}</TableTd>
<TableTd>{formatRupiah(item.value)}</TableTd>
<TableTd>
<Button color='green' onClick={() => router.push(`/admin/ekonomi/PADesa-pendapatan-asli-desa/pendapatan/${item.id}`)}>
<IconEdit size={20} />
@@ -107,7 +115,7 @@ function ListPendapatan({ search }: { search: string }) {
<Text fw={'bold'}>Total</Text>
</TableTd>
<TableTd>
{pendapatanState.findMany.data.reduce((total, item) => total + item.value, 0)}
{formatRupiah(pendapatanState.findMany.data.reduce((total, item) => total + item.value, 0))}
</TableTd>
</TableTr>
</TableTbody>