Disable Option

This commit is contained in:
Stephen Gesityan 2025-05-08 02:11:39 +07:00
parent 7c88680e65
commit 4de8cac352
5 changed files with 59 additions and 16 deletions

View File

@ -27,7 +27,7 @@ class LoginController extends Controller
*
* @var string
*/
protected $redirectTo = '/home';
protected $redirectTo = '/';
/**
* Create a new controller instance.
@ -48,7 +48,7 @@ public function logout(Request $request)
$request->session()->regenerateToken();
session()->flash('error', 'Berhasil logout!');
return redirect('/home');
return redirect('/');
}
protected function authenticated(Request $request, $user)

View File

@ -28,7 +28,7 @@ class RegisterController extends Controller
*
* @var string
*/
protected $redirectTo = '/home';
protected $redirectTo = '/';
/**
* Create a new controller instance.

View File

@ -22,14 +22,13 @@ public function store(Request $request) {
$conflict = Booking::where('table_id', $request->table_id)
->where(function($query) use ($request) {
$query->whereBetween('start_time', [$request->start_time, $request->end_time])
->orWhereBetween('end_time', [$request->start_time, $request->end_time])
->orWhere(function($query) use ($request) {
$query->where('start_time', '<', $request->start_time)
->where('end_time', '>', $request->end_time);
});
})
->where('status', '!=', 'cancelled') // skip booking yang dibatalkan
->exists();
$query->where('start_time', '<', $request->start_time)
->where('end_time', '>', $request->start_time);
});
})
->where('status', '!=', 'cancelled') // skip booking yang dibatalkan
->exists();
if ($conflict) {
return response()->json(['message' => 'Meja sudah dibooking di jam tersebut'], 409);
@ -45,4 +44,25 @@ public function store(Request $request) {
return response()->json(['message' => 'Booking berhasil']);
}
public function getBookedSchedules(Request $request) {
$request->validate([
'table_id' => 'required|exists:tables,id',
'date' => 'required|date',
]);
$bookings = Booking::where('table_id', $request->table_id)
->whereDate('start_time', $request->date)
->where('status', '!=', 'cancelled')
->select('start_time', 'end_time')
->get()
->map(function ($booking) {
return [
'start' => Carbon::parse($booking->start_time)->format('H:i'),
'end' => Carbon::parse($booking->end_time)->format('H:i')
];
});
return response()->json($bookings);
}
}

View File

@ -26,8 +26,8 @@ class="flex items-center bg-[url('/public/images/map.jpg')] bg-cover bg-center p
</div>
</div>
@foreach ($venue['tables'] as $table)
<div x-data="booking(@json(auth()->check()))" class="border rounded-lg shadow-md p-4 mb-4">
<div class="flex items-center justify-between cursor-pointer" @click="open = !open">
<div x-data="booking(@json(auth()->check()), '{{ $table['id'] }}')" class="border rounded-lg shadow-md p-4 mb-4">
<div class="flex items-center justify-between cursor-pointer" @click="open = !open; if(open) checkBookedSchedules()">
<div class="flex items-center">
<img src="{{ asset('images/meja.jpg') }}" class="w-24">
<div class="ml-4">
@ -50,7 +50,10 @@ class="flex items-center bg-[url('/public/images/map.jpg')] bg-cover bg-center p
<select class="w-full border p-2 rounded-lg" x-model="selectedTime">
<option value="">-- Pilih Jam --</option>
<template x-for="hour in getHoursInRange(9, 22)" :key="hour">
<option :value="hour + ':00'" x-text="hour + ':00'"></option>
<option :value="hour + ':00'"
:disabled="isTimeBooked(hour + ':00')"
x-text="hour + ':00' + (isTimeBooked(hour + ':00') ? ' (Booked)' : '')">
</option>
</template>
</select>
@ -88,21 +91,40 @@ function updateClock() {
updateClock();
document.addEventListener('alpine:init', () => {
Alpine.data('booking', (isLoggedIn) => ({
Alpine.data('booking', (isLoggedIn, tableId) => ({
isLoggedIn,
tableId,
open: false,
selectedTime: '',
selectedDuration: '',
isLoading: false,
bookedSchedules: [],
getHoursInRange(startHour, endHour) {
let hours = [];
for (let i = startHour; i <= endHour; i++) {
hours.push(i);
hours.push(i.toString().padStart(2, '0'));
}
return hours;
},
isTimeBooked(time) {
const timeFormatted = time.padStart(5, '0');
return this.bookedSchedules.some(schedule => {
return timeFormatted >= schedule.start && timeFormatted < schedule.end;
});
},
async checkBookedSchedules() {
const today = new Date().toISOString().split('T')[0];
try {
const response = await fetch(`/booking/schedules?table_id=${this.tableId}&date=${today}`);
this.bookedSchedules = await response.json();
} catch (error) {
console.error('Error checking booked schedules:', error);
}
},
submitBooking(tableId, tableName) {
if (!this.isLoggedIn) {
alert('Silahkan login terlebih dahulu untuk melakukan booking.');

View File

@ -10,9 +10,10 @@
use Illuminate\Support\Facades\Auth;
Auth::routes();
Route::get('/home', [HomeController::class, "index"])->name('index');
Route::get('/', [HomeController::class, "index"])->name('index');
Route::get('/venue/{venueName}', [VenueController::class, "venue"])->name('venue');
Route::post('/booking', [BookingController::class, 'store'])->name('booking.store');
Route::get('/booking/schedules', [BookingController::class, 'getBookedSchedules'])->name('booking.schedules');
Route::middleware(['auth', 'is_admin'])->prefix('admin')->group(function () {
Route::get('/', [AdminController::class, 'index'])->name('admin.dashboard');
Route::get('/bookings', [BookingsController::class, 'index'])->name('admin.bookings.index');