batas waktu
This commit is contained in:
parent
4cd4abccd7
commit
f5f2056e86
|
@ -35,6 +35,7 @@
|
|||
use Barryvdh\DomPDF\Facade\Pdf;
|
||||
use Filament\Forms\Components\Modal;
|
||||
use Filament\Forms\Components\FileUpload;
|
||||
use Illuminate\Support\Facades\Storage;
|
||||
|
||||
class ReservasiiResource extends Resource
|
||||
{
|
||||
|
@ -97,6 +98,12 @@ public static function form(Form $form): Form
|
|||
->imageCropAspectRatio('16:9')
|
||||
->imageResizeTargetWidth('1920')
|
||||
->imageResizeTargetHeight('1080')
|
||||
->preserveFilenames()
|
||||
->downloadable()
|
||||
->openable()
|
||||
->deleteUploadedFileUsing(function ($file) {
|
||||
Storage::disk('public')->delete($file);
|
||||
})
|
||||
->columnSpanFull(),
|
||||
])
|
||||
])->columnSpan(1),
|
||||
|
@ -216,8 +223,7 @@ public static function table(Table $table): Table
|
|||
return $table
|
||||
->columns([
|
||||
Tables\Columns\TextColumn::make('nama')
|
||||
->label('Nama')
|
||||
->searchable(),
|
||||
->label('Nama'),
|
||||
|
||||
Tables\Columns\TextColumn::make('tanggal')
|
||||
->date('d F Y')
|
||||
|
@ -229,8 +235,7 @@ public static function table(Table $table): Table
|
|||
|
||||
Tables\Columns\TextColumn::make('detail.paketFoto.nama_paket_foto')
|
||||
->label('Paket Foto')
|
||||
->listWithLineBreaks()
|
||||
->searchable(),
|
||||
->listWithLineBreaks(),
|
||||
|
||||
Tables\Columns\TextColumn::make('total')
|
||||
->money('IDR'),
|
||||
|
|
|
@ -27,12 +27,21 @@ protected function getHeaderActions(): array
|
|||
//}
|
||||
|
||||
public function getTabs(): array{
|
||||
return[
|
||||
null => \Filament\Resources\Components\Tab::make('Semua'),
|
||||
'Paket Pasangan' => \Filament\Resources\Components\Tab::make()->query(fn($query) => $query->whereRelation('detail.paketFoto', 'nama_paket_foto', 'Paket Pasangan')),
|
||||
'Paket 5 orang' => \Filament\Resources\Components\Tab::make()->query(fn($query) => $query->whereRelation('detail.paketFoto', 'nama_paket_foto', 'Paket 5 Orang')),
|
||||
'Widebox Couple' => \Filament\Resources\Components\Tab::make()->query(fn($query) => $query->whereRelation('detail.paketFoto', 'nama_paket_foto', 'Widebox Couple')),
|
||||
'Widebox Group' => \Filament\Resources\Components\Tab::make()->query(fn($query) => $query->whereRelation('detail.paketFoto', 'nama_paket_foto', 'Widebox Group')),
|
||||
$paketFotos = \App\Models\PaketFoto::orderBy('nama_paket_foto')->get();
|
||||
|
||||
$tabs = [
|
||||
null => \Filament\Resources\Components\Tab::make('Semua Paket')
|
||||
->badge(fn () => \App\Models\Reservasii::count())
|
||||
->icon('heroicon-o-photo'),
|
||||
];
|
||||
|
||||
foreach ($paketFotos as $paketFoto) {
|
||||
$tabs[$paketFoto->id] = \Filament\Resources\Components\Tab::make($paketFoto->nama_paket_foto)
|
||||
->query(fn($query) => $query->whereRelation('detail.paketFoto', 'nama_paket_foto', $paketFoto->nama_paket_foto))
|
||||
->badge(fn () => \App\Models\Reservasii::whereRelation('detail.paketFoto', 'nama_paket_foto', $paketFoto->nama_paket_foto)->count())
|
||||
->icon('heroicon-o-camera');
|
||||
}
|
||||
|
||||
return $tabs;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -118,8 +118,9 @@ public function updateUnavailableTimes()
|
|||
{
|
||||
if ($this->tanggal) {
|
||||
// Ambil waktu yang sudah dipesan dari database untuk tanggal yang dipilih
|
||||
// dan paket foto yang sama
|
||||
// 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);
|
||||
})
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
use Livewire\Component;
|
||||
use Livewire\WithFileUploads;
|
||||
use Livewire\Attributes\Title;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
#[Title('Upload Bukti Pembayaran - SiKolaself')]
|
||||
class UploadBuktiPembayaran extends Component
|
||||
|
@ -15,6 +17,8 @@ class UploadBuktiPembayaran extends Component
|
|||
public $booking;
|
||||
public $bukti_pembayaran;
|
||||
public $bookingId;
|
||||
public $timeLeft;
|
||||
public $isExpired = false;
|
||||
|
||||
public function mount($id)
|
||||
{
|
||||
|
@ -32,10 +36,48 @@ public function mount($id)
|
|||
if ($this->booking->status_pembayaran === 'approved') {
|
||||
return redirect()->route('booking.success', $this->booking->id);
|
||||
}
|
||||
|
||||
// Check if booking is expired
|
||||
$createdAt = Carbon::parse($this->booking->created_at);
|
||||
$expiryTime = $createdAt->addMinutes(5);
|
||||
|
||||
if (Carbon::now()->gt($expiryTime)) {
|
||||
// Update status pembayaran menjadi rejected
|
||||
$this->booking->update(['status_pembayaran' => 'rejected']);
|
||||
|
||||
// Hapus reservasi ini dari daftar waktu yang tidak tersedia
|
||||
DB::table('unavailable_times')
|
||||
->where('tanggal', $this->booking->tanggal)
|
||||
->where('waktu', $this->booking->waktu)
|
||||
->where('reservasii_id', $this->booking->id)
|
||||
->delete();
|
||||
|
||||
$this->isExpired = true;
|
||||
session()->flash('error', 'Waktu upload bukti pembayaran telah habis. Reservasi ditolak.');
|
||||
return redirect()->route('histori');
|
||||
}
|
||||
|
||||
$this->timeLeft = Carbon::now()->diffInSeconds($expiryTime);
|
||||
}
|
||||
|
||||
public function getTimeLeftProperty()
|
||||
{
|
||||
if ($this->isExpired) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
$createdAt = Carbon::parse($this->booking->created_at);
|
||||
$expiryTime = $createdAt->addMinutes(5);
|
||||
return max(0, Carbon::now()->diffInSeconds($expiryTime));
|
||||
}
|
||||
|
||||
public function uploadBuktiPembayaran()
|
||||
{
|
||||
if ($this->isExpired) {
|
||||
session()->flash('error', 'Waktu upload bukti pembayaran telah habis.');
|
||||
return redirect()->route('histori');
|
||||
}
|
||||
|
||||
$this->validate([
|
||||
'bukti_pembayaran' => 'required|image|max:2048', // max 2MB
|
||||
], [
|
||||
|
|
|
@ -25,7 +25,8 @@ class Reservasii extends Model
|
|||
protected $casts = [
|
||||
'tanggal' => 'date',
|
||||
'waktu' => 'datetime',
|
||||
'total' => 'decimal:2'
|
||||
'total' => 'decimal:2',
|
||||
'bukti_pembayaran' => 'array'
|
||||
];
|
||||
|
||||
public function user()
|
||||
|
|
|
@ -1,65 +1,41 @@
|
|||
<div class="w-full max-w-[85rem] max-h-screen py-10 px-4 sm:px-6 lg:px-8 mx-auto">
|
||||
<section class="overflow-hidden bg-white py-11 font-poppins dark:bg-gray-800">
|
||||
<div class="w-full max-w-[85rem] py-10 px-4 sm:px-6 lg:px-8 mx-auto">
|
||||
<section class="overflow-hidden bg-white py-6 sm:py-11 font-poppins dark:bg-gray-800">
|
||||
<div class="max-w-6xl px-4 py-4 mx-auto lg:py-8 md:px-6">
|
||||
|
||||
|
||||
<div class="flex flex-wrap -mx-4">
|
||||
<div class="flex flex-col md:flex-row -mx-4">
|
||||
<!-- Bagian Gambar -->
|
||||
<div class="w-full mb-8 md:w-1/2 md:mb-0" x-data="{ mainImage: '{{ url('storage', $paketfoto->gambar) }}' }">
|
||||
<div class="sticky top-0 z-50 overflow-hidden ">
|
||||
<div class="aspect-[4/3] ">
|
||||
<img x-bind:src="mainImage" alt="" class="object-cover w-full lg:h-full ">
|
||||
<div class="sticky top-0 z-50 overflow-hidden">
|
||||
<div class="aspect-[4/3]">
|
||||
<img x-bind:src="mainImage" alt="{{ $paketfoto->nama_paket_foto }}" class="object-cover w-full h-full rounded-lg shadow-lg">
|
||||
</div>
|
||||
<div class="flex-wrap hidden md:flex ">
|
||||
<div class="flex-wrap hidden md:flex mt-4">
|
||||
<div class="w-1/2 p-2 sm:w-1/4" x-on:click="mainImage='https://m.media-amazon.com/images/I/71f5Eu5lJSL._SX679_.jpg'">
|
||||
<alt="" class="object-cover w-full lg:h-20 cursor-pointer hover:border hover:border-blue-500">
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div class="px-6 pb-6 mt-6 border-t border-gray-300 dark:border-gray-400 ">
|
||||
<div class="flex flex-wrap items-center mt-6">
|
||||
{{-- <span class="mr-2">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="w-4 h-4 text-gray-700 dark:text-gray-400 bi bi-truck" viewBox="0 0 16 16">
|
||||
<path d="M0 3.5A1.5 1.5 0 0 1 1.5 2h9A1.5 1.5 0 0 1 12 3.5V5h1.02a1.5 1.5 0 0 1 1.17.563l1.481 1.85a1.5 1.5 0 0 1 .329.938V10.5a1.5 1.5 0 0 1-1.5 1.5H14a2 2 0 1 1-4 0H5a2 2 0 1 1-3.998-.085A1.5 1.5 0 0 1 0 10.5v-7zm1.294 7.456A1.999 1.999 0 0 1 4.732 11h5.536a2.01 2.01 0 0 1 .732-.732V3.5a.5.5 0 0 0-.5-.5h-9a.5.5 0 0 0-.5.5v7a.5.5 0 0 0 .294.456zM12 10a2 2 0 0 1 1.732 1h.768a.5.5 0 0 0 .5-.5V8.35a.5.5 0 0 0-.11-.312l-1.48-1.85A.5.5 0 0 0 13.02 6H12v4zm-9 1a1 1 0 1 0 0 2 1 1 0 0 0 0-2zm9 0a1 1 0 1 0 0 2 1 1 0 0 0 0-2z">
|
||||
</path>
|
||||
</svg>
|
||||
</span>
|
||||
<h2 class="text-lg font-bold text-gray-700 dark:text-gray-400">Free Shipping</h2>--}}
|
||||
{{-- <img src="https://m.media-amazon.com/images/I/71f5Eu5lJSL._SX679_.jpg" alt="Thumbnail" class="object-cover w-full h-20 rounded cursor-pointer hover:border-2 hover:border-blue-500">--}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="w-full px-4 md:w-1/2 ">
|
||||
|
||||
<!-- Bagian Informasi -->
|
||||
<div class="w-full px-4 md:w-1/2">
|
||||
<div class="lg:pl-20">
|
||||
<div class="mb-8 ">
|
||||
<h2 class="max-w-xl mb-6 text-2xl font-bold dark:text-gray-400 md:text-4xl">
|
||||
{{ $paketfoto->nama_paket_foto }}
|
||||
</h2>
|
||||
<p class="inline-block mb-6 text-4xl font-bold text-gray-700 dark:text-gray-400 ">
|
||||
<span>
|
||||
{{ Number::currency($paketfoto->harga_paket_foto, 'IDR') }}
|
||||
</span>
|
||||
{{-- <span class="text-base font-normal text-gray-500 line-through dark:text-gray-400">$1800.99</span> --}}
|
||||
<div class="mb-8">
|
||||
<h2 class="max-w-xl mb-4 text-xl sm:text-2xl md:text-4xl font-bold dark:text-gray-400">
|
||||
{{ $paketfoto->nama_paket_foto }}
|
||||
</h2>
|
||||
<p class="inline-block mb-6 text-2xl sm:text-3xl md:text-4xl font-bold text-gray-700 dark:text-gray-400">
|
||||
<span>{{ Number::currency($paketfoto->harga_paket_foto, 'IDR') }}</span>
|
||||
</p>
|
||||
<p class="max-w-md text-sm sm:text-base text-gray-700 dark:text-gray-400">
|
||||
{{ $paketfoto->fasilitas }}
|
||||
</p>
|
||||
<p class="max-w-md text-gray-700 dark:text-gray-400">
|
||||
{{ $paketfoto->fasilitas }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="w-32 mb-8 ">
|
||||
<div class="flex flex-col items-start">
|
||||
<a href="{{ route('booking', ['id' => $paketfoto->id]) }}" class="px-6 py-3 bg-blue-500 rounded-md text-white hover:bg-blue-600 dark:bg-blue-500 dark:hover:bg-blue-700">
|
||||
Reservasi
|
||||
</a>
|
||||
</div>
|
||||
{{-- <label for="" class="w-full pb-1 text-xl font-semibold text-gray-700 border-b border-blue-300 dark:border-gray-600 dark:text-gray-400">Quantity</label>
|
||||
<div class="relative flex flex-row w-full h-10 mt-6 bg-transparent rounded-lg"> --}}
|
||||
|
||||
{{-- <button class="w-20 h-full text-gray-600 bg-gray-300 rounded-l outline-none cursor-pointer dark:hover:bg-gray-700 dark:text-gray-400 hover:text-gray-700 dark:bg-gray-900 hover:bg-gray-400">
|
||||
<span class="m-auto text-2xl font-thin">-</span>
|
||||
</button>
|
||||
<input type="number" readonly class="flex items-center w-full font-semibold text-center text-gray-700 placeholder-gray-700 bg-gray-300 outline-none dark:text-gray-400 dark:placeholder-gray-400 dark:bg-gray-900 focus:outline-none text-md hover:text-black" placeholder="1">
|
||||
<button class="w-20 h-full text-gray-600 bg-gray-300 rounded-r outline-none cursor-pointer dark:hover:bg-gray-700 dark:text-gray-400 dark:bg-gray-900 hover:text-gray-700 hover:bg-gray-400">
|
||||
<span class="m-auto text-2xl font-thin">+</span>
|
||||
</button> --}}
|
||||
<div class="w-full sm:w-32 mb-8">
|
||||
<div class="flex flex-col items-start">
|
||||
<a href="{{ route('booking', ['id' => $paketfoto->id]) }}"
|
||||
class="w-full sm:w-auto px-6 py-3 text-center bg-blue-500 rounded-md text-white hover:bg-blue-600 dark:bg-blue-500 dark:hover:bg-blue-700 transition duration-300">
|
||||
Reservasi
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -2,9 +2,26 @@
|
|||
<div class="flex items-center font-poppins">
|
||||
<div class="w-full px-4 py-4 mx-auto bg-white border rounded-lg shadow-sm">
|
||||
<div>
|
||||
<h1 class="mb-6 text-xl font-semibold text-gray-700">
|
||||
Upload Bukti Pembayaran
|
||||
</h1>
|
||||
<div class="flex justify-between items-center mb-6">
|
||||
<h1 class="text-xl font-semibold text-gray-700">
|
||||
Upload Bukti Pembayaran
|
||||
</h1>
|
||||
<div class="text-right">
|
||||
<p class="text-sm text-gray-600">Sisa Waktu</p>
|
||||
<p class="font-medium text-red-600"
|
||||
x-data="{
|
||||
timeLeft: {{ $this->timeLeft }},
|
||||
formatTime(seconds) {
|
||||
const minutes = Math.floor(seconds / 60);
|
||||
const remainingSeconds = Math.floor(seconds % 60);
|
||||
return `${minutes}:${remainingSeconds.toString().padStart(2, '0')}`;
|
||||
}
|
||||
}"
|
||||
x-init="setInterval(() => { if(timeLeft > 0) timeLeft--; }, 1000)"
|
||||
x-text="formatTime(timeLeft)">
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Informasi Pelanggan -->
|
||||
<div class="mb-6 p-4 bg-gray-50 rounded-lg">
|
||||
|
@ -61,8 +78,8 @@
|
|||
<div>
|
||||
<p class="text-sm text-gray-600">Jumlah yang Harus Dibayar</p>
|
||||
<p class="font-medium">
|
||||
@if($booking->tipe_pembayaran === 'dp')
|
||||
Rp {{ number_format(max(20000, $booking->total * 0.3), 0, ',', '.') }}
|
||||
@if(strtolower($booking->tipe_pembayaran) === 'dp')
|
||||
Rp {{ number_format(20000, 0, ',', '.') }}
|
||||
<span class="text-xs text-gray-500 block">(Minimal 30% atau Rp 20.000)</span>
|
||||
@else
|
||||
Rp {{ number_format($booking->total, 0, ',', '.') }}
|
||||
|
@ -73,8 +90,8 @@
|
|||
@if($booking->metode_pembayaran === 'transfer')
|
||||
<div class="md:col-span-2">
|
||||
<p class="text-sm text-gray-600">Nomor Rekening</p>
|
||||
<p class="font-medium">1234567890 (Bank BCA)</p>
|
||||
<p class="text-xs text-gray-500">a.n. Nama Studio Foto</p>
|
||||
<p class="font-medium">116101022592507 (Bank BRI)</p>
|
||||
<p class="text-xs text-gray-500">a.n. Adella Novita</p>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
<td>{{ $index + 1 }}</td>
|
||||
<td>{{ $reservasi->nama }}</td>
|
||||
<td>{{ $reservasi->tanggal->format('d F Y') }}</td>
|
||||
<td>{{ $reservasi->waktu }}</td>
|
||||
<td>{{ \Carbon\Carbon::parse($reservasi->waktu)->format('H:i') }}</td>
|
||||
<td>
|
||||
@foreach($reservasi->detail as $detail)
|
||||
{{ $detail->paketFoto->nama_paket_foto }}<br>
|
||||
|
|
Loading…
Reference in New Issue