import { Button } from '@/components/ui/button'; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, } from "@/components/ui/dialog" import { Field, FieldGroup } from "@/components/ui/field" import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { Expense } from '@/types'; import { useForm, router } from '@inertiajs/react'; import { useEffect, useState, useRef } from 'react'; import expenseRoutes from '@/routes/expense'; import { toast } from 'sonner'; import { NumericFormat } from 'react-number-format'; import { ImagePlus, X } from 'lucide-react'; interface ExpenseFormModalProps { isOpen: boolean; onClose: () => void; expense: Expense | null; } export function ExpenseFormModal({ isOpen, onClose, expense }: ExpenseFormModalProps) { const isEditing = !!expense; const fileInputRef = useRef(null); const [imagePreview, setImagePreview] = useState(null); const { data, setData, post, processing, errors, reset, clearErrors } = useForm<{ name: string; amount: string; image: File | null; }>({ name: '', amount: '', image: null, }); useEffect(() => { if (expense) { setData({ name: expense.name, amount: expense.amount.toString(), image: null, }); setImagePreview(expense.proof_url || null); } else { reset(); setImagePreview(null); } }, [expense]); const handleClose = () => { onClose(); setTimeout(() => { reset(); setImagePreview(null); clearErrors(); }, 200); }; const onImageChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { setData('image', file); const reader = new FileReader(); reader.onloadend = () => { setImagePreview(reader.result as string); }; reader.readAsDataURL(file); } }; const removeImage = () => { setData('image', null); setImagePreview(null); if (fileInputRef.current) { fileInputRef.current.value = ''; } }; const onSubmit = (e: React.FormEvent) => { e.preventDefault(); if (isEditing && expense) { router.post(expenseRoutes.update(expense.id).url, { ...data, _method: 'PATCH', }, { onSuccess: (response: any) => { toast.success(response.props.flash.success); handleClose(); }, }); } else { post(expenseRoutes.store().url, { onSuccess: (response: any) => { toast.success(response.props.flash.success); handleClose(); }, }); } }; return ( !open && handleClose()}> {isEditing ? 'Ubah Pengeluaran' : 'Tambah Pengeluaran'}
setData('name', e.target.value)} autoComplete='off' placeholder='Contoh: Bayar Listrik' maxLength={100} /> {errors.name &&

{errors.name}

}
{ setData('amount', values.value) }} placeholder="Rp 0" autoComplete='off' /> {errors.amount &&

{errors.amount}

}
{imagePreview ? (
Preview
) : (
fileInputRef.current?.click()} className="h-40 w-full flex flex-col items-center justify-center border-2 border-dashed rounded-lg cursor-pointer hover:bg-accent/50 transition-colors" > Klik untuk upload bukti PNG, JPG up to 5MB
)}
{errors.image &&

{errors.image}

}
); }