/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; import { useProxy } from 'valtio/utils'; import apbdes from '@/app/admin/(dashboard)/_state/landing-page/apbdes'; import { useState } from 'react'; import { toast } from 'react-toastify'; import { Box, Button, Group, Paper, Stack, Text, TextInput, NumberInput, Title, Table, TableThead, TableTbody, TableTr, TableTh, TableTd, ActionIcon, Badge, Modal, Divider, Center, } from '@mantine/core'; import { IconPlus, IconEdit, IconTrash, IconCalendar, IconCoin, } from '@tabler/icons-react'; interface RealisasiManagerProps { itemId: string; itemKode: string; itemUraian: string; itemAnggaran: number; itemTotalRealisasi: number; itemPersentase: number; realisasiItems: any[]; } export default function RealisasiManager({ itemId, itemKode, itemUraian, itemAnggaran, itemTotalRealisasi, itemPersentase, realisasiItems, }: RealisasiManagerProps) { const state = useProxy(apbdes); const [modalOpened, setModalOpened] = useState(false); const [editingId, setEditingId] = useState(null); const [loading, setLoading] = useState(false); // Form state const [formData, setFormData] = useState({ kode: '', jumlah: 0, tanggal: new Date().toISOString().split('T')[0], // YYYY-MM-DD format for input keterangan: '', }); const resetForm = () => { setFormData({ kode: '', jumlah: 0, tanggal: new Date().toISOString().split('T')[0], keterangan: '', }); setEditingId(null); }; const handleOpenCreate = () => { resetForm(); setModalOpened(true); }; const handleOpenEdit = (realisasi: any) => { const tanggal = new Date(realisasi.tanggal); const tanggalStr = tanggal.toISOString().split('T')[0]; // YYYY-MM-DD setFormData({ kode: realisasi.kode || '', jumlah: realisasi.jumlah, tanggal: tanggalStr, keterangan: realisasi.keterangan || '', }); setEditingId(realisasi.id); setModalOpened(true); }; const handleSubmit = async () => { if (formData.jumlah <= 0) { return toast.warn('Jumlah realisasi harus lebih dari 0'); } if (!formData.kode || formData.kode.trim() === '') { return toast.warn('Kode realisasi wajib diisi'); } try { setLoading(true); if (editingId) { // Update existing realisasi const success = await state.realisasi.update(editingId, { kode: formData.kode, jumlah: formData.jumlah, tanggal: new Date(formData.tanggal).toISOString(), keterangan: formData.keterangan, }); if (success) { toast.success('Realisasi berhasil diperbarui'); } } else { // Create new realisasi const success = await state.realisasi.create(itemId, { kode: formData.kode, jumlah: formData.jumlah, tanggal: new Date(formData.tanggal).toISOString(), keterangan: formData.keterangan, }); if (success) { toast.success('Realisasi berhasil ditambahkan'); } } setModalOpened(false); resetForm(); } catch (error: any) { console.error('Error saving realisasi:', error); toast.error(error?.message || 'Gagal menyimpan realisasi'); } finally { setLoading(false); } }; const handleDelete = async (realisasiId: string) => { if (!confirm('Apakah Anda yakin ingin menghapus realisasi ini?')) { return; } try { setLoading(true); const success = await state.realisasi.delete(realisasiId); if (success) { toast.success('Realisasi berhasil dihapus'); } } catch (error: any) { console.error('Error deleting realisasi:', error); toast.error(error?.message || 'Gagal menghapus realisasi'); } finally { setLoading(false); } }; const formatRupiah = (amount: number) => { return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', minimumFractionDigits: 0, maximumFractionDigits: 0, }).format(amount); }; const formatDate = (dateString: string) => { return new Date(dateString).toLocaleDateString('id-ID', { year: 'numeric', month: 'long', day: 'numeric', }); }; const getSisaAnggaran = () => { return itemAnggaran - itemTotalRealisasi; }; const getPersentaseColor = (persen: number) => { if (persen >= 100) return 'teal'; if (persen >= 80) return 'blue'; if (persen >= 60) return 'yellow'; return 'red'; }; return ( {/* Header */} {itemKode} - {itemUraian} Kelola realisasi untuk item ini {/* Summary Cards */} ANGGARAN {formatRupiah(itemAnggaran)} TOTAL REALISASI {formatRupiah(itemTotalRealisasi)} = 0 ? 'green.0' : 'red.0'}> = 0 ? 'green.9' : 'red.9'} fw={600}> SISA ANGGARAN = 0 ? 'green.9' : 'red.9'} fw={700}> {formatRupiah(getSisaAnggaran())} PERSENTASE {itemPersentase.toFixed(2)}% {/* Realisasi List */} {realisasiItems && realisasiItems.length > 0 ? ( Daftar Realisasi ({realisasiItems.length}) Kode Tanggal Uraian Jumlah Aksi {realisasiItems.map((realisasi) => ( {realisasi.kode || '-'} {formatDate(realisasi.tanggal)} {realisasi.keterangan || '-'} {formatRupiah(realisasi.jumlah)} handleOpenEdit(realisasi)} > handleDelete(realisasi.id)} disabled={loading} > ))}
) : (
Belum ada realisasi untuk item ini Klik tombol "Tambah Realisasi" untuk menambahkan
)} {/* Modal Create/Edit */} { setModalOpened(false); resetForm(); }} title={ {editingId ? 'Edit Realisasi' : 'Tambah Realisasi Baru'} } size="md" centered > {/* Info Item */} Item: {itemKode} - {itemUraian} Anggaran: {formatRupiah(itemAnggaran)} Sudah terealisasi: {formatRupiah(itemTotalRealisasi)} setFormData({ ...formData, kode: e.target.value })} description="Kode unik untuk realisasi ini" required /> setFormData({ ...formData, jumlah: Number(val) || 0 })} leftSection={} thousandSeparator min={0} step={100000} required /> setFormData({ ...formData, tanggal: e.target.value })} leftSection={} required /> setFormData({ ...formData, keterangan: e.target.value })} description="Deskripsi singkat tentang realisasi ini" />
); }