390 lines
20 KiB
TypeScript
390 lines
20 KiB
TypeScript
import InputError from '@/components/input-error';
|
|
import { Button } from '@/components/ui/button';
|
|
import { Input } from '@/components/ui/input';
|
|
import { Label } from '@/components/ui/label';
|
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
|
import AppLayout from '@/layouts/app-layout';
|
|
import { type BreadcrumbItem } from '@/types';
|
|
import { Head, useForm } from '@inertiajs/react';
|
|
|
|
interface RegistrationFormProps {
|
|
mode: 'create' | 'edit';
|
|
registration?: {
|
|
id?: string;
|
|
registration_number: string;
|
|
patient_id: string;
|
|
employee_id: string;
|
|
service_room_id: string;
|
|
insurance_id: string;
|
|
registration_type: string;
|
|
patient_type: string;
|
|
registration_datetime: string;
|
|
discharge_datetime?: string;
|
|
estimated_discharge?: string;
|
|
complaint: string;
|
|
medical_notes?: string;
|
|
diagnoses?: any[];
|
|
prescriptions?: any[];
|
|
status: string;
|
|
payment_status: string;
|
|
is_referral: boolean;
|
|
referral_from?: string;
|
|
need_icu: boolean;
|
|
is_active: boolean;
|
|
};
|
|
patients: { id: string; name: string }[];
|
|
employees: { id: string; name: string }[];
|
|
serviceRooms: { id: string; name: string }[];
|
|
insurances: { id: string; name: string }[];
|
|
registrationTypes: string[];
|
|
patientTypes: string[];
|
|
statusOptions?: string[];
|
|
paymentStatusOptions?: string[];
|
|
}
|
|
|
|
const breadcrumbs: BreadcrumbItem[] = [
|
|
{ title: 'Dashboard', href: '/dashboard' },
|
|
{ title: 'Registrasi Pasien', href: '/registrations' },
|
|
{ title: 'Form Registrasi', href: '#' },
|
|
];
|
|
|
|
export default function RegistrationForm({
|
|
mode,
|
|
registration,
|
|
patients = [],
|
|
employees = [],
|
|
serviceRooms = [],
|
|
insurances = [],
|
|
registrationTypes = ['Rawat Jalan', 'Rawat Inap', 'UGD'],
|
|
patientTypes = ['Umum', 'BPJS', 'Asuransi', 'Perusahaan', 'Gratis'],
|
|
statusOptions = ['registered', 'in_progress', 'completed', 'cancelled'],
|
|
paymentStatusOptions = ['unpaid', 'partial', 'paid', 'insurance_cover'],
|
|
}: RegistrationFormProps) {
|
|
const { data, setData, post, put, processing, errors, reset } = useForm({
|
|
registration_number: registration?.registration_number || '',
|
|
patient_id: registration?.patient_id || '',
|
|
employee_id: registration?.employee_id || '',
|
|
service_room_id: registration?.service_room_id || '',
|
|
insurance_id: registration?.insurance_id || '',
|
|
registration_type: registration?.registration_type || 'Rawat Jalan',
|
|
patient_type: registration?.patient_type || 'Umum',
|
|
registration_datetime: registration?.registration_datetime || new Date().toISOString(),
|
|
estimated_discharge: registration?.estimated_discharge || '',
|
|
complaint: registration?.complaint || '',
|
|
medical_notes: registration?.medical_notes || '',
|
|
diagnoses: registration?.diagnoses || [],
|
|
prescriptions: registration?.prescriptions || [],
|
|
status: registration?.status || 'registered',
|
|
payment_status: registration?.payment_status || 'unpaid',
|
|
is_referral: registration?.is_referral ?? false,
|
|
referral_from: registration?.referral_from || '',
|
|
need_icu: registration?.need_icu ?? false,
|
|
is_active: registration?.is_active ?? true,
|
|
});
|
|
|
|
const onSubmit = (e: React.FormEvent) => {
|
|
e.preventDefault();
|
|
if (mode === 'create') {
|
|
post(route('registrations.store'), {
|
|
onSuccess: () => reset(),
|
|
});
|
|
} else {
|
|
put(route('registrations.update', registration?.id), {
|
|
preserveScroll: true,
|
|
});
|
|
}
|
|
};
|
|
|
|
return (
|
|
<AppLayout breadcrumbs={breadcrumbs}>
|
|
<Head title={`${mode === 'create' ? 'Tambah' : 'Edit'} Registrasi`} />
|
|
|
|
<div className="flex h-full flex-1 flex-col gap-4 rounded-xl p-4">
|
|
<div className="flex items-center justify-between">
|
|
<h1 className="text-2xl font-bold">{mode === 'create' ? 'Tambah Registrasi Baru' : 'Edit Data Registrasi'}</h1>
|
|
</div>
|
|
|
|
<form onSubmit={onSubmit} className="space-y-6">
|
|
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
{/* Nomor Registrasi */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="registration_number">Nomor Registrasi*</Label>
|
|
<Input
|
|
id="registration_number"
|
|
value={data.registration_number}
|
|
onChange={(e) => setData('registration_number', e.target.value)}
|
|
placeholder="Otomatis dihasilkan"
|
|
disabled={true}
|
|
/>
|
|
<InputError message={errors.registration_number} />
|
|
</div>
|
|
|
|
{/* Pilih Pasien */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="patient_id">Pasien*</Label>
|
|
<Select value={data.patient_id} onValueChange={(value) => setData('patient_id', value)}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Pilih Pasien" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{patients.map((patient) => (
|
|
<SelectItem key={patient.id} value={patient.id}>
|
|
{patient.name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<InputError message={errors.patient_id} />
|
|
</div>
|
|
|
|
{/* Pilih Dokter */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="employee_id">Dokter*</Label>
|
|
<Select value={data.employee_id} onValueChange={(value) => setData('employee_id', value)}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Pilih Dokter" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{employees.map((employee) => (
|
|
<SelectItem key={employee.id} value={employee.id}>
|
|
{employee.name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<InputError message={errors.employee_id} />
|
|
</div>
|
|
|
|
{/* Pilih Ruangan */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="service_room_id">Ruangan*</Label>
|
|
<Select value={data.service_room_id} onValueChange={(value) => setData('service_room_id', value)}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Pilih Ruangan" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{serviceRooms.map((room) => (
|
|
<SelectItem key={room.id} value={room.id}>
|
|
{room.name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<InputError message={errors.service_room_id} />
|
|
</div>
|
|
|
|
{/* Pilih Asuransi */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="insurance_id">Asuransi</Label>
|
|
<Select value={data.insurance_id} onValueChange={(value) => setData('insurance_id', value)}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Pilih Asuransi" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{insurances.map((insurance) => (
|
|
<SelectItem key={insurance.id} value={insurance.id}>
|
|
{insurance.name}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<InputError message={errors.insurance_id} />
|
|
</div>
|
|
|
|
{/* Jenis Registrasi */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="registration_type">Tipe Registrasi*</Label>
|
|
<Select value={data.registration_type} onValueChange={(value) => setData('registration_type', value)}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Pilih Tipe" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{registrationTypes.map((type) => (
|
|
<SelectItem key={type} value={type}>
|
|
{type}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<InputError message={errors.registration_type} />
|
|
</div>
|
|
|
|
{/* Jenis Pasien */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="patient_type">Tipe Pasien*</Label>
|
|
<Select value={data.patient_type} onValueChange={(value) => setData('patient_type', value)}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Pilih Tipe Pasien" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{patientTypes.map((type) => (
|
|
<SelectItem key={type} value={type}>
|
|
{type}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<InputError message={errors.patient_type} />
|
|
</div>
|
|
|
|
{/* Tanggal Registrasi */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="registration_datetime">Waktu Registrasi*</Label>
|
|
<Input
|
|
id="registration_datetime"
|
|
type="datetime-local"
|
|
value={data.registration_datetime.slice(0, 16)}
|
|
onChange={(e) => setData('registration_datetime', e.target.value)}
|
|
/>
|
|
<InputError message={errors.registration_datetime} />
|
|
</div>
|
|
|
|
{/* Perkiraan Tanggal Pulang */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="estimated_discharge">Perkiraan Waktu Pulang</Label>
|
|
<Input
|
|
id="estimated_discharge"
|
|
type="datetime-local"
|
|
value={data.estimated_discharge?.slice(0, 16) || ''}
|
|
onChange={(e) => setData('estimated_discharge', e.target.value)}
|
|
/>
|
|
<InputError message={errors.estimated_discharge} />
|
|
</div>
|
|
|
|
{/* Keluhan */}
|
|
<div className="space-y-2 md:col-span-2">
|
|
<Label htmlFor="complaint">Keluhan*</Label>
|
|
<Input
|
|
id="complaint"
|
|
value={data.complaint}
|
|
onChange={(e) => setData('complaint', e.target.value)}
|
|
placeholder="Keluhan pasien"
|
|
/>
|
|
<InputError message={errors.complaint} />
|
|
</div>
|
|
|
|
{/* Rujukan */}
|
|
<div className="space-y-2">
|
|
<div className="flex items-center space-x-2">
|
|
<input
|
|
type="checkbox"
|
|
id="is_referral"
|
|
checked={data.is_referral}
|
|
onChange={(e) => setData('is_referral', e.target.checked)}
|
|
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
|
|
/>
|
|
<Label htmlFor="is_referral">Rujukan</Label>
|
|
</div>
|
|
<InputError message={errors.is_referral} />
|
|
</div>
|
|
|
|
{data.is_referral && (
|
|
<div className="space-y-2">
|
|
<Label htmlFor="referral_from">Rujukan Dari*</Label>
|
|
<Input
|
|
id="referral_from"
|
|
value={data.referral_from}
|
|
onChange={(e) => setData('referral_from', e.target.value)}
|
|
placeholder="Asal rujukan"
|
|
/>
|
|
<InputError message={errors.referral_from} />
|
|
</div>
|
|
)}
|
|
|
|
{/* Butuh ICU */}
|
|
<div className="space-y-2">
|
|
<div className="flex items-center space-x-2">
|
|
<input
|
|
type="checkbox"
|
|
id="need_icu"
|
|
checked={data.need_icu}
|
|
onChange={(e) => setData('need_icu', e.target.checked)}
|
|
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
|
|
/>
|
|
<Label htmlFor="need_icu">Butuh ICU</Label>
|
|
</div>
|
|
<InputError message={errors.need_icu} />
|
|
</div>
|
|
|
|
{/* Status */}
|
|
{mode === 'edit' && (
|
|
<>
|
|
<div className="space-y-2">
|
|
<Label htmlFor="status">Status Registrasi*</Label>
|
|
<Select value={data.status} onValueChange={(value) => setData('status', value)}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Pilih Status" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{statusOptions.map((status) => (
|
|
<SelectItem key={status} value={status}>
|
|
{status === 'registered'
|
|
? 'Terdaftar'
|
|
: status === 'in_progress'
|
|
? 'Dalam Proses'
|
|
: status === 'completed'
|
|
? 'Selesai'
|
|
: 'Dibatalkan'}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<InputError message={errors.status} />
|
|
</div>
|
|
|
|
{/* Status Pembayaran */}
|
|
<div className="space-y-2">
|
|
<Label htmlFor="payment_status">Status Pembayaran*</Label>
|
|
<Select value={data.payment_status} onValueChange={(value) => setData('payment_status', value)}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Pilih Status Pembayaran" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
{paymentStatusOptions.map((status) => (
|
|
<SelectItem key={status} value={status}>
|
|
{status === 'unpaid'
|
|
? 'Belum Lunas'
|
|
: status === 'partial'
|
|
? 'Sebagian'
|
|
: status === 'paid'
|
|
? 'Lunas'
|
|
: 'Ditanggung Asuransi'}
|
|
</SelectItem>
|
|
))}
|
|
</SelectContent>
|
|
</Select>
|
|
<InputError message={errors.payment_status} />
|
|
</div>
|
|
</>
|
|
)}
|
|
|
|
{/* Aktif */}
|
|
{mode === 'edit' && (
|
|
<div className="flex items-center space-x-2">
|
|
<input
|
|
type="checkbox"
|
|
id="is_active"
|
|
checked={data.is_active}
|
|
onChange={(e) => setData('is_active', e.target.checked)}
|
|
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
|
|
/>
|
|
<Label htmlFor="is_active">Aktif</Label>
|
|
<InputError message={errors.is_active} />
|
|
</div>
|
|
)}
|
|
</div>
|
|
|
|
<div className="flex justify-end gap-2">
|
|
<Button variant="outline" type="button" onClick={() => window.history.back()}>
|
|
Batal
|
|
</Button>
|
|
<Button type="submit" disabled={processing}>
|
|
{mode === 'create' ? 'Simpan' : 'Perbarui'} Registrasi
|
|
</Button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</AppLayout>
|
|
);
|
|
}
|