# Story 7.6: Booking Limit Indicator ## Epic Reference **Epic 7:** Client Dashboard ## Dependencies - **Story 7.5:** New Booking Interface (provides booking page where indicator displays) - **Story 3.3:** Availability Calendar (calendar component to integrate with) ## User Story As a **client**, I want **to see my booking status and limits clearly**, So that **I understand when I can book consultations**. ## Acceptance Criteria ### Display Locations - [ ] Dashboard widget showing booking status - [ ] Booking page status banner ### Status Messages - [ ] "You can book a consultation today" (when no booking exists for today) - [ ] "You already have a booking for today" (when pending/approved booking exists for today) - [ ] "You have a pending request for [date]" (shows first pending request date) ### Calendar Integration - [ ] Pass `bookedDates` array to availability calendar component - [ ] Calendar marks user's booked dates as unavailable (distinct styling) - [ ] Visual indicator differentiates "user already booked" from "no slots available" ### Information - [ ] Clear messaging about 1-per-day limit - [ ] Bilingual messages (Arabic/English) ### Edge Cases - [ ] Handle multiple pending requests (show count or list) - [ ] Handle cancelled bookings (should not block new booking) - [ ] Loading state while fetching booking status ## Technical Notes ### Files to Create - `resources/views/livewire/client/booking-status.blade.php` - Reusable status component ### Files to Modify - `resources/views/livewire/client/dashboard.blade.php` - Add booking status widget - `resources/views/livewire/client/booking.blade.php` - Add status banner (from Story 7.5) - `resources/lang/en/booking.php` - Add translation keys - `resources/lang/ar/booking.php` - Add translation keys ### Component Implementation ```php user(); $todayBooking = $user->consultations() ->whereDate('scheduled_date', today()) ->whereIn('status', ['pending', 'approved']) ->first(); $pendingRequests = $user->consultations() ->where('status', 'pending') ->where('scheduled_date', '>=', today()) ->orderBy('scheduled_date') ->get(); $upcomingApproved = $user->consultations() ->where('status', 'approved') ->where('scheduled_date', '>=', today()) ->get(); return [ 'canBookToday' => is_null($todayBooking), 'todayBooking' => $todayBooking, 'pendingRequests' => $pendingRequests, 'upcomingApproved' => $upcomingApproved, 'bookedDates' => $user->consultations() ->whereIn('status', ['pending', 'approved']) ->where('scheduled_date', '>=', today()) ->pluck('scheduled_date') ->map(fn($d) => $d->format('Y-m-d')) ->toArray(), ]; } public function with(): array { return $this->getBookingStatus(); } }; ?>
``` ### Template ```blade
{{-- Loading State --}}
@if($canBookToday)
{{ __('booking.can_book_today') }}
@else
{{ __('booking.already_booked_today') }}
@endif @if($pendingRequests->isNotEmpty())
@if($pendingRequests->count() === 1)

{{ __('booking.pending_for_date', ['date' => $pendingRequests->first()->scheduled_date->format('d/m/Y')]) }}

@else

{{ __('booking.pending_count', ['count' => $pendingRequests->count()]) }}

    @foreach($pendingRequests->take(3) as $request)
  • {{ $request->scheduled_date->format('d/m/Y') }}
  • @endforeach
@endif
@endif

{{ __('booking.limit_message') }}

``` ### Translation Keys ```php // resources/lang/en/booking.php return [ 'can_book_today' => 'You can book a consultation today', 'already_booked_today' => 'You already have a booking for today', 'pending_for_date' => 'You have a pending request for :date', 'pending_count' => 'You have :count pending requests', 'limit_message' => 'Note: You can book a maximum of 1 consultation per day.', ]; // resources/lang/ar/booking.php return [ 'can_book_today' => 'يمكنك حجز استشارة اليوم', 'already_booked_today' => 'لديك حجز بالفعل لهذا اليوم', 'pending_for_date' => 'لديك طلب معلق بتاريخ :date', 'pending_count' => 'لديك :count طلبات معلقة', 'limit_message' => 'ملاحظة: يمكنك حجز استشارة واحدة كحد أقصى في اليوم.', ]; ``` ### Calendar Integration Pass `bookedDates` to the availability calendar from Story 3.3: ```blade {{-- In booking page --}} ``` The calendar should style user's booked dates differently (e.g., with a badge or distinct color) from dates with no available slots. ## Test Scenarios ### Unit Tests - `getBookingStatus()` returns correct structure - `canBookToday` is true when no booking exists for today - `canBookToday` is false when pending booking exists for today - `canBookToday` is false when approved booking exists for today - Cancelled bookings do not affect `canBookToday` - `bookedDates` only includes pending and approved bookings ### Feature Tests - Status displays "can book today" message for new users - Status displays "already booked" when user has today's booking - Status displays pending request date correctly - Multiple pending requests display count and dates - Component renders on dashboard page - Component renders on booking page - Messages display correctly in Arabic locale - Messages display correctly in English locale ### Browser Tests (optional) - Calendar visually shows user's booked dates as unavailable - Status updates after successful booking submission ## References - **PRD Section 5.8:** Client Dashboard - Booking limit status requirement - **PRD Section 5.4:** "Maximum 1 consultation per client per day" - **Epic 7 Success Criteria:** "Booking limit enforcement (1 per day)" ## Definition of Done - [ ] Booking status component created - [ ] Status displays on dashboard - [ ] Status displays on booking page - [ ] Calendar highlights user's booked dates - [ ] Messages are accurate for all states - [ ] Bilingual support (AR/EN) - [ ] Loading state implemented - [ ] Edge cases handled (multiple pending, cancelled) - [ ] Unit tests pass - [ ] Feature tests pass - [ ] Code formatted with Pint ## Estimation **Complexity:** Low | **Effort:** 2-3 hours