import { Button } from '@/components/ui/button'; import { Calendar } from '@/components/ui/calendar'; import { Input } from '@/components/ui/input'; import { Label } from '@/components/ui/label'; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select'; import { useForm } from '@inertiajs/react'; import AppLayout from '@/layouts/app-layout'; import { Head } from '@inertiajs/react'; import { type BreadcrumbItem } from '@/types'; import InputError from '@/components/input-error'; import { format } from 'date-fns'; import { CalendarIcon } from 'lucide-react'; import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover'; import { cn } from '@/lib/utils'; import { Textarea } from '@/components/ui/textarea'; import { useState, useEffect } from 'react'; interface TransactionFormProps { mode: 'create' | 'edit'; patients: Array<{ id: string; name: string }>; registrations: Array<{ id: string; registration_number: string; patient_name: string }>; insurances: Array<{ id: string; name: string }>; procedures: Array<{ id: string; code: string; name: string }>; employees: Array<{ id: string; name: string }>; paymentMethods: Record; statusOptions: Record; transaction?: { id?: string; transaction_number: string; registration_id?: string; patient_id?: string; insurance_id?: string; procedure_id?: string; employee_id?: string; service_name: string; description?: string; transaction_datetime: string; subtotal: number; tax_amount: number; discount_amount: number; grand_total: number; payment_method: string; status: string; paid_amount: number; insurance_covered_amount: number; details?: string; notes?: string; }; } const breadcrumbs: BreadcrumbItem[] = [ { title: 'Dashboard', href: '/dashboard' }, { title: 'Transaksi', href: '/transactions' }, { title: 'Form', href: '#' }, ]; const toLocalISOString = (date: Date) => { const offset = date.getTimezoneOffset(); const localDate = new Date(date.getTime() - (offset * 60 * 1000)); return localDate.toISOString().split('T')[0]; }; export default function TransactionForm({ mode, patients, registrations, insurances, procedures, employees, paymentMethods, statusOptions, transaction }: TransactionFormProps) { const { data, setData, post, put, processing, errors, reset } = useForm({ transaction_number: transaction?.transaction_number || '', registration_id: transaction?.registration_id || '', patient_id: transaction?.patient_id || '', insurance_id: transaction?.insurance_id || '', procedure_id: transaction?.procedure_id || '', employee_id: transaction?.employee_id || '', service_name: transaction?.service_name || '', transaction_datetime: transaction?.transaction_datetime || toLocalISOString(new Date()), subtotal: transaction?.subtotal || 0, tax_amount: transaction?.tax_amount || 0, discount_amount: transaction?.discount_amount || 0, grand_total: transaction?.grand_total || 0, payment_method: transaction?.payment_method || 'cash', status: transaction?.status || 'pending', paid_amount: transaction?.paid_amount || 0, insurance_covered_amount: transaction?.insurance_covered_amount || 0, notes: transaction?.notes || '', details: transaction?.details || '', }); const [registrationSelected, setRegistrationSelected] = useState(false); useEffect(() => { const calculatedGrandTotal = data.subtotal + data.tax_amount - data.discount_amount; setData('grand_total', calculatedGrandTotal); if (data.payment_method === 'insurance') { const insuranceCovered = calculatedGrandTotal * 0.8; // Example: insurance covers 80% setData('insurance_covered_amount', insuranceCovered); setData('paid_amount', calculatedGrandTotal - insuranceCovered); } else { setData('insurance_covered_amount', 0); setData('paid_amount', calculatedGrandTotal); } }, [data.subtotal, data.tax_amount, data.discount_amount, data.payment_method]); useEffect(() => { if (data.registration_id) { const selectedRegistration = registrations.find(r => r.id === data.registration_id); if (selectedRegistration) { setRegistrationSelected(true); const patient = patients.find(p => p.name === selectedRegistration.patient_name); if (patient) { setData('patient_id', patient.id); } } } else { setRegistrationSelected(false); } }, [data.registration_id, registrations, patients]); useEffect(() => { if (data.procedure_id) { const selectedProcedure = procedures.find(p => p.id === data.procedure_id); if (selectedProcedure) { setData('service_name', selectedProcedure.name); } } }, [data.procedure_id, procedures]); const onSubmit = (e: React.FormEvent) => { e.preventDefault(); if (mode === 'create') { post(route('transactions.store'), { onSuccess: () => reset(), }); } else { put(route('transactions.update', transaction?.id), { preserveScroll: true, }); } }; const formatCurrency = (value: number) => { return new Intl.NumberFormat('id-ID', { style: 'currency', currency: 'IDR', minimumFractionDigits: 0, }).format(value); }; return (

{mode === 'create' ? 'Tambah Transaksi Baru' : 'Edit Data Transaksi'}

{mode === 'edit' && ( No. Transaksi {data.transaction_number} )}
setData('service_name', e.target.value)} placeholder="Nama layanan" />
date && setData('transaction_datetime', toLocalISOString(date))} initialFocus />
{/* Financial Section */}
setData('subtotal', Math.max(0, parseFloat(e.target.value) || 0))} placeholder="Subtotal" />
setData('tax_amount', Math.max(0, parseFloat(e.target.value) || 0))} placeholder="Jumlah pajak" />
setData('discount_amount', Math.max(0, parseFloat(e.target.value) || 0))} placeholder="Jumlah diskon" />
{formatCurrency(data.grand_total)}
{data.payment_method === 'insurance' && ( <>
{ const insuranceCovered = Math.max(0, parseFloat(e.target.value) || 0); setData('insurance_covered_amount', insuranceCovered); setData('paid_amount', data.grand_total - insuranceCovered); }} placeholder="Jumlah dibayar asuransi" />
)}
{ const paidAmount = Math.max(0, parseFloat(e.target.value) || 0); setData('paid_amount', paidAmount); if (data.payment_method === 'insurance') { setData('insurance_covered_amount', data.grand_total - paidAmount); } }} placeholder="Jumlah pembayaran" />