diff --git a/app/Http/Controllers/Admin/BookingController.php b/app/Http/Controllers/Admin/BookingController.php index dbd1d9b..23029fa 100644 --- a/app/Http/Controllers/Admin/BookingController.php +++ b/app/Http/Controllers/Admin/BookingController.php @@ -13,19 +13,38 @@ class BookingController extends Controller public function activeIndex(Request $request): \Illuminate\View\View { $parkingLotId = $request->get('parking_lot_id'); - $parkingLots = ParkingLot::active()->get(['id', 'name']); + $search = $request->get('search'); + $parkingLots = ParkingLot::active()->get(['id', 'name']); - $query = Booking::with('parkingLot') - ->where('status', 'active') - ->orderBy('start_time', 'desc'); + $base = Booking::with('parkingLot')->where('status', 'active'); + + // Summary stats (always across all lots/filters) + $stats = [ + 'total' => (clone $base)->count(), + 'walkin' => (clone $base)->where('source', 'walk_in')->count(), + 'reservation' => (clone $base)->where('source', 'reservation')->count(), + 'overdue' => (clone $base)->where('end_time', '<', now())->count(), + ]; + + // Filtered query + $query = (clone $base)->orderBy('start_time', 'asc'); if ($parkingLotId) { $query->where('parking_lot_id', $parkingLotId); } + if ($search) { + $query->where(function ($q) use ($search) { + $q->where('vehicle_plate', 'like', "%{$search}%") + ->orWhere('customer_name', 'like', "%{$search}%") + ->orWhere('phone', 'like', "%{$search}%"); + }); + } $activeBookings = $query->paginate(50); - return view('admin.bookings.active', compact('activeBookings', 'parkingLots', 'parkingLotId')); + return view('admin.bookings.active', compact( + 'activeBookings', 'parkingLots', 'parkingLotId', 'stats', 'search' + )); } public function completeBooking(Request $request, Booking $booking): JsonResponse diff --git a/resources/views/admin/bookings/active.blade.php b/resources/views/admin/bookings/active.blade.php index b4b42ad..2ffbc4b 100644 --- a/resources/views/admin/bookings/active.blade.php +++ b/resources/views/admin/bookings/active.blade.php @@ -2,106 +2,322 @@ @section('title', 'الحجوزات النشطة — دمشق باركينغ') @section('page-title', 'الحجوزات النشطة') +@section('styles') + +@endsection + @section('content') -{{-- ── Header ──────────────────────────────────────────────────────────────── --}} +{{-- ── Page header ─────────────────────────────────────────────────────────── --}}

الحجوزات النشطة

- السيارات المسجّلة حالياً · يتجدد كل 30 ثانية + السيارات داخل المواقف حالياً

- - - {{ $activeBookings->total() }} نشط - تحديث بعد 30ث +
-{{-- ── Filter ────────────────────────────────────────────────────────────────── --}} -
-
-
-
- - +{{-- ── Stat cards ───────────────────────────────────────────────────────────── --}} +
+
+
+
+
- @if(request('parking_lot_id')) -
- - إلغاء الفلتر - +
+
{{ $stats['total'] }}
+
إجمالي النشطة
+
+
+
+
+
+
+ +
+
+
{{ $stats['walkin'] }}
+
دخول مباشر
+
+
+
+
+
+
+ +
+
+
{{ $stats['reservation'] }}
+
حجوزات مسبقة
+
+
+
+
+
+
+ +
+
+
+ {{ $stats['overdue'] }} +
+
متأخرة عن الخروج
- @endif
-{{-- ── Table ────────────────────────────────────────────────────────────────── --}} +{{-- ── Filter bar ───────────────────────────────────────────────────────────── --}} +
+
+ +
+ + +
+ +
+ +
+ + + + +
+
+ +
+ + @if(request('parking_lot_id') || request('search')) + + مسح + + @endif +
+ +
+
+ +{{-- ── Bookings table ───────────────────────────────────────────────────────── --}}
+ +
+ + + قائمة الحجوزات + + + {{ $activeBookings->total() }} سجل + +
+
- + - - - - + + @forelse($activeBookings as $booking) - + @php + $elapsedMin = $booking->start_time->diffInMinutes(now()); + $remainMins = now()->diffInMinutes($booking->end_time, false); + $isOverdue = $remainMins < 0; + $isWarning = !$isOverdue && $remainMins < 15; + $totalMins = max(1, $booking->start_time->diffInMinutes($booking->end_time)); + $pctUsed = min(100, round($elapsedMin / $totalMins * 100)); + $barColor = $isOverdue ? '#ef4444' : ($isWarning ? '#f59e0b' : '#10b981'); + $rowClass = $isOverdue ? 'is-overdue' : ($isWarning ? 'is-warning' : 'is-ok'); + $source = $booking->source ?? 'walk_in'; + @endphp + + + {{-- Plate + source --}} - - + + {{-- Driver --}} + + {{-- Lot --}} + - - + + {{-- Entry time --}} + + {{-- Duration / status --}} + + + {{-- Action --}} + @empty - @@ -119,58 +335,66 @@ {{ $activeBookings->appends(request()->query())->links('pagination::bootstrap-5') }} @endif + @push('scripts') @endpush
رقم اللوحةالسيارة السائقالهاتف الموقف وقت الدخولوقت الخروجالمدةإنهاءالمدة / الوضعإجراء
- - {{ $booking->vehicle_plate ?? $booking->customer_name ?? '--' }} + + {{ $booking->vehicle_plate ?? '—' }} +
+ @if($source === 'walk_in') + + مباشر + + @else + + حجز + + @endif +
{{ $booking->user_name ?? $booking->customer_name ?? '--' }} - {{ $booking->user_phone ?? $booking->phone ?? '--' }} - - +
+ {{ $booking->customer_name ?? '—' }} +
+ @if($booking->phone) +
+ {{ $booking->phone }} +
+ @endif +
+ {{ $booking->parkingLot->name }} {{ $booking->start_time->format('Y/m/d H:i') }}{{ $booking->end_time->format('Y/m/d H:i') }} - - {{ $booking->start_time->diffForHumans(now(), true) }} - +
+ {{ $booking->start_time->format('H:i') }} +
+
+ {{ $booking->start_time->format('d/m/Y') }} +
+ @if($isOverdue) + + + تجاوز {{ floor(abs($remainMins)/60) > 0 ? floor(abs($remainMins)/60).'س ' : '' }}{{ abs($remainMins)%60 }}د + + @elseif($isWarning) + + + متبقي {{ $remainMins }}د + + @else + + + {{ floor($elapsedMin/60) }}س {{ $elapsedMin%60 }}د + + @endif +
+
+
+
- -

لا توجد حجوزات نشطة

+
+ +

لا توجد حجوزات نشطة

جميع المواقف خالية حالياً