si-klinik/sk-klinik.my.id/app/Livewire/Patient/BookingAntrean.php

127 lines
4.5 KiB
PHP

<?php
namespace App\Livewire\Patient;
use App\Models\Appointment;
use Livewire\Component;
use Livewire\WithPagination;
use Illuminate\Support\Facades\Auth;
use Masmerise\Toaster\Toaster;
class BookingAntrean extends Component
{
use WithPagination;
public $appointment_date;
public $notes;
public $showTicket = false;
public $selectedAppointment = null;
public $doctor_id;
public $service_category_id;
public $filter_doctor = '';
protected $messages = [
'appointment_date.required' => 'Tanggal pendaftaran wajib diisi.',
'appointment_date.after_or_equal' => 'Tanggal pendaftaran tidak boleh di masa lalu.',
'service_category_id.required' => 'Poli / Layanan wajib dipilih.',
'service_category_id.exists' => 'Poli yang dipilih tidak valid.',
'doctor_id.required' => 'Dokter wajib dipilih.',
'doctor_id.exists' => 'Dokter yang dipilih tidak valid.',
'notes.required' => 'Keluhan singkat wajib diisi.',
'notes.max' => 'Keluhan singkat tidak boleh lebih dari 255 karakter.',
];
public function mount()
{
$this->appointment_date = date('Y-m-d');
$this->service_category_id = \App\Models\ServiceCategory::first()?->id;
$this->doctor_id = \App\Models\Doctor::first()?->id;
}
// Fungsi untuk membatalkan antrean
public function cancelAppointment($id)
{
$appointment = Appointment::where('patient_id', Auth::id())
->where('status', 'waiting')
->findOrFail($id);
$appointment->update(['status' => 'cancelled']);
Toaster::success('Antrean berhasil dibatalkan.');
}
// Fungsi untuk mengambil data tiket dan buka modal
public function showTicketModal($id)
{
$this->selectedAppointment = Appointment::with('patient')->findOrFail($id);
// Pastikan variabel showTicket tetap true jika Anda masih menggunakannya untuk @if di blade
$this->showTicket = true;
// Membuka modal menggunakan Flux Javascript API
$this->js("Flux.modal('ticket-modal').show()");
}
public function save()
{
$this->validate([
'appointment_date' => 'required|date|after_or_equal:today',
'doctor_id' => 'required|exists:doctors,id',
'service_category_id' => 'required|exists:service_categories,id',
'notes' => 'required|string|max:255',
]);
// Cek duplikasi: 1 pasien, 1 hari, 1 dokter
$exists = Appointment::where('patient_id', Auth::id())
->where('doctor_id', $this->doctor_id)
->whereDate('appointment_date', $this->appointment_date)
->exists();
if ($exists) {
Toaster::error('Anda sudah terdaftar untuk dokter ini di tanggal tersebut.');
return;
}
// Nomor antrean spesifik per DOKTER dan per TANGGAL
$lastQueue = Appointment::where('doctor_id', $this->doctor_id)
->whereDate('appointment_date', $this->appointment_date)
->max('queue_number') ?? 0;
$newApp = Appointment::create([
'patient_id' => Auth::id(),
'doctor_id' => $this->doctor_id,
'service_category_id' => $this->service_category_id,
'appointment_date' => $this->appointment_date,
'queue_number' => $lastQueue + 1,
'notes' => $this->notes,
'status' => 'waiting',
'created_by' => Auth::id(),
]);
$this->reset(['notes', 'doctor_id', 'service_category_id']);
$this->showTicketModal($newApp->id);
}
public function render()
{
// Ambil nomor yang statusnya 'calling' hari ini
$currentCalling = Appointment::whereDate('appointment_date', date('Y-m-d'))
->where('status', 'calling')
->when($this->filter_doctor, function ($query) {
return $query->where('doctor_id', $this->filter_doctor);
})
->with(['patient', 'doctor', 'serviceCategory']) // Eager load agar tidak error
->latest('updated_at') // Ambil yang paling baru dipanggil
->first();
return view('livewire.patient.booking-antrean', [
'myAppointments' => Appointment::where('patient_id', Auth::id())
->latest()
->paginate(5),
'currentCalling' => $currentCalling, // Kirim ke view
'categories' => \App\Models\ServiceCategory::all(), // Data Poli
'doctors' => \App\Models\Doctor::all(), // Data Dokter
]);
}
}