MIF_E31222582/app/Livewire/BookingPage.php

260 lines
8.2 KiB
PHP

<?php
namespace App\Livewire;
use App\Models\PaketFoto;
use App\Models\Reservasii;
use Livewire\Attributes\Title;
use Livewire\Component;
use Livewire\Attributes\On;
#[Title('Booking - SiKolaself')]
class BookingPage extends Component
{
public $paketfoto;
public $selectedPakets = [];
public $showModal = false;
public $search = '';
public $pakets;
public $nama = '';
public $tanggal = '';
public $waktu = '';
public $warna = '';
public $promo = '';
public $tipe_pembayaran = '';
public $bookedTimes = [];
public $unavailableTimes = [];
public $promoApplied = false;
public $promoDiscount = 0;
public $promoData = null;
public function mount($id = null)
{
if ($id) {
$this->paketfoto = PaketFoto::findOrFail($id);
$this->selectedPakets[] = [
'id' => $this->paketfoto->id,
'nama' => $this->paketfoto->nama_paket_foto,
'harga' => $this->paketfoto->harga_paket_foto,
'gambar' => $this->paketfoto->gambar,
'warna' => ''
];
} else {
$this->paketfoto = PaketFoto::first();
}
$this->tanggal = now()->format('Y-m-d');
$this->updateUnavailableTimes();
$this->loadPakets();
}
public function loadPakets()
{
$this->pakets = PaketFoto::where('nama_paket_foto', 'like', '%' . $this->search . '%')
->get();
}
public function updatedSearch()
{
$this->loadPakets();
}
#[On('paket-added')]
public function handlePaketAdded($paketId)
{
$paket = PaketFoto::find($paketId);
if ($paket) {
// Cek apakah paket sudah ada di selectedPakets
$exists = collect($this->selectedPakets)->contains('id', $paket->id);
if (!$exists) {
$this->selectedPakets[] = [
'id' => $paket->id,
'nama' => $paket->nama_paket_foto,
'harga' => $paket->harga_paket_foto,
'gambar' => $paket->gambar,
'warna' => ''
];
}
}
}
public function addPaket($paketId)
{
$paket = PaketFoto::find($paketId);
if ($paket) {
// Cek apakah paket sudah ada di selectedPakets
$exists = collect($this->selectedPakets)->contains('id', $paket->id);
if (!$exists) {
$this->selectedPakets[] = [
'id' => $paket->id,
'nama' => $paket->nama_paket_foto,
'harga' => $paket->harga_paket_foto,
'gambar' => $paket->gambar,
'warna' => ''
];
}
}
$this->showModal = false;
}
public function removePaket($index)
{
unset($this->selectedPakets[$index]);
$this->selectedPakets = array_values($this->selectedPakets);
}
public function updatePaketWarna($index, $warna)
{
$this->selectedPakets[$index]['warna'] = $warna;
}
public function updatedTanggal()
{
$this->waktu = ''; // Reset waktu yang dipilih
$this->updateUnavailableTimes();
}
public function updateUnavailableTimes()
{
if ($this->tanggal) {
// Ambil waktu yang sudah dipesan dari database untuk tanggal yang dipilih
// dan paket foto yang sama, hanya yang statusnya approved
$this->bookedTimes = Reservasii::where('tanggal', $this->tanggal)
->where('status_pembayaran', 'approved') // Hanya ambil yang sudah approved
->whereHas('detail', function($query) {
$query->where('paket_foto_id', $this->paketfoto->id);
})
->pluck('waktu')
->map(function($time) {
return $time->format('H:i');
})
->toArray();
// Daftar semua waktu yang tersedia dari jam 8 pagi sampai 8 malam
$allTimes = collect(range(8, 20))->map(function($hour) {
return str_pad($hour, 2, '0', STR_PAD_LEFT) . ':00';
})->toArray();
// Jika hari ini, tambahkan waktu yang sudah lewat
if ($this->tanggal == now()->format('Y-m-d')) {
$currentTime = now()->format('H:i');
$pastTimes = array_filter($allTimes, function($time) use ($currentTime) {
return $time <= $currentTime;
});
$this->unavailableTimes = array_merge($this->bookedTimes, $pastTimes);
} else {
$this->unavailableTimes = $this->bookedTimes;
}
}
}
public function getUnavailableTimesProperty()
{
return $this->unavailableTimes;
}
public function getBookedTimesProperty()
{
return $this->bookedTimes;
}
public function applyPromo()
{
$this->promoApplied = false;
$this->promoDiscount = 0;
$this->promoData = null;
if (empty($this->promo)) {
return;
}
$promo = \App\Models\Promo::where('kode', $this->promo)
->where('aktif', true)
->first();
if (!$promo) {
$this->addError('promo', 'Kode promo tidak valid');
return;
}
$this->promoData = $promo;
$this->promoApplied = true;
// Hitung diskon berdasarkan tipe promo
if ($promo->tipe === 'fix') {
$this->promoDiscount = $promo->diskon;
} else if ($promo->tipe === 'persen') {
$this->promoDiscount = ($this->paketfoto->harga_paket_foto * $promo->diskon) / 100;
}
}
public function getTotalPriceProperty()
{
$total = collect($this->selectedPakets)->sum('harga');
if ($this->promoApplied) {
$total -= $this->promoDiscount;
}
return max(0, $total);
}
public function placeOrder()
{
$this->validate([
'nama' => 'required|min:3',
'tanggal' => 'required|date|after_or_equal:today',
'waktu' => 'required',
'warna' => 'required',
'promo' => '',
'tipe_pembayaran' => 'required',
'selectedPakets' => 'required|array|min:1',
], [
'nama.required' => 'Nama lengkap harus diisi',
'nama.min' => 'Nama lengkap minimal 3 karakter',
'tanggal.required' => 'Tanggal booking harus diisi',
'tanggal.after_or_equal' => 'Tanggal booking tidak boleh sebelum hari ini',
'waktu.required' => 'Waktu booking harus dipilih',
'warna.required' => 'Background harus dipilih',
'tipe_pembayaran.required' => 'Tipe pembayaran harus dipilih',
'selectedPakets.required' => 'Pilih minimal satu paket foto',
'selectedPakets.min' => 'Pilih minimal satu paket foto',
]);
if (in_array($this->waktu, $this->unavailableTimes)) {
$this->addError('waktu', 'Waktu yang dipilih tidak tersedia');
return;
}
$reservasi = Reservasii::create([
'user_id' => auth()->id(),
'nama' => $this->nama,
'tanggal' => $this->tanggal,
'waktu' => $this->waktu,
'promo_id' => $this->promoData ? $this->promoData->id : null,
'total' => $this->totalPrice,
'tipe_pembayaran' => $this->tipe_pembayaran,
'metode_pembayaran' => 'transfer',
'status_pembayaran' => 'pending'
]);
foreach ($this->selectedPakets as $paket) {
$reservasi->detail()->create([
'paket_foto_id' => $paket['id'],
'warna' => $this->warna,
'jumlah' => 1,
'harga' => $paket['harga'],
'total_harga' => $paket['harga'],
]);
}
session()->flash('message', 'Booking berhasil dibuat! Silahkan upload bukti pembayaran.');
return redirect()->route('upload.bukti.pembayaran', $reservasi->id);
}
public function render()
{
// Update unavailable times setiap kali halaman di-render
$this->updateUnavailableTimes();
return view('livewire.booking-page');
}
}