# Story 7.1: Client Dashboard Overview ## Epic Reference **Epic 7:** Client Dashboard ## User Story As a **client**, I want **a dashboard showing my key information at a glance**, So that **I can quickly see upcoming consultations and case updates**. ## Dependencies ### Epic Dependencies | Epic | Dependency | Status | |------|------------|--------| | Epic 1 | Authentication system, base UI layout | Required | | Epic 2 | User model with client data | Required | | Epic 3 | Consultation model and booking system | Required | | Epic 4 | Timeline and TimelineUpdate models | Required | ### Model Prerequisites The following models and relationships must exist before implementation: **User Model** (`app/Models/User.php`): - `consultations()` - HasMany relationship to Consultation - `timelines()` - HasMany relationship to Timeline **Consultation Model** (`app/Models/Consultation.php`): - `approved()` scope - filters `status = 'approved'` - `pending()` scope - filters `status = 'pending'` - `upcoming()` scope - filters `scheduled_date >= today()` - `scheduled_date` column (date) - `scheduled_time` column (time) - `type` column (enum: 'free', 'paid') - `status` column (enum: 'pending', 'approved', 'rejected', 'completed', 'no-show', 'cancelled') **Timeline Model** (`app/Models/Timeline.php`): - `active()` scope - filters `status = 'active'` - `user_id` foreign key - `updates()` - HasMany relationship to TimelineUpdate **TimelineUpdate Model** (`app/Models/TimelineUpdate.php`): - `timeline()` - BelongsTo relationship to Timeline - `update_text` column - `created_at` timestamp ## Acceptance Criteria ### Welcome Section - [ ] Display "Welcome, {client name}" greeting - [ ] Use localized greeting based on user's preferred language - [ ] Show current date in user's locale format ### Upcoming Consultations Widget - [ ] Display next approved consultation (or "No upcoming consultations" if none) - [ ] Show consultation date/time formatted per locale (AR: DD/MM/YYYY, EN: MM/DD/YYYY) - [ ] Show time in 12-hour format (AM/PM) - [ ] Display type badge: "Free" (green) or "Paid" (gold) - [ ] Display status badge with appropriate color - [ ] "View Details" link to consultation details (Story 7.2) ### Active Cases Widget - [ ] Display count of active timelines - [ ] Show preview of most recent update (truncated to ~100 chars) - [ ] "View All Cases" link to timelines list (Story 7.3) - [ ] Empty state: "No active cases" with muted styling ### Recent Updates Widget - [ ] Display last 3 timeline updates across all user's cases - [ ] Each update shows: case name, update date, preview text - [ ] "View Timeline" link for each update - [ ] Empty state: "No recent updates" ### Booking Status Widget - [ ] Display count of pending booking requests - [ ] Show booking limit indicator: - Can book: "You can book a consultation today" (green) - Cannot book: "You already have a booking for today" (amber) - [ ] "Book Consultation" button linking to booking page (Story 7.5) - [ ] Disable button if daily limit reached ### Design Requirements - [ ] Card-based layout using Flux UI components - [ ] Color scheme: Navy (#0A1F44) background sections, Gold (#D4AF37) accents - [ ] Mobile-first responsive (stack cards vertically on mobile) - [ ] All text content bilingual (Arabic RTL / English LTR) - [ ] Use consistent spacing: `gap-6` between cards, `p-6` card padding ### Edge Cases & Empty States - [ ] No consultations: Show empty state with "Book your first consultation" CTA - [ ] No timelines: Show empty state "No cases assigned yet" - [ ] No updates: Show empty state "No recent updates" - [ ] Loading state: Show skeleton loaders while data fetches ## Technical Implementation ### Files to Create/Modify | File | Action | Purpose | |------|--------|---------| | `resources/views/livewire/client/dashboard.blade.php` | Create | Main Volt component | | `routes/web.php` | Modify | Add client dashboard route | | `resources/views/components/layouts/client.blade.php` | Create/Verify | Client layout if not exists | ### Route Configuration ```php // routes/web.php Route::middleware(['auth', 'verified'])->prefix('client')->group(function () { Route::get('/dashboard', function () { return view('livewire.client.dashboard'); })->name('client.dashboard'); }); ``` ### Component Structure ```php user(); return [ 'upcomingConsultation' => $user->consultations() ->approved() ->upcoming() ->orderBy('scheduled_date') ->orderBy('scheduled_time') ->first(), 'activeTimelinesCount' => $user->timelines()->active()->count(), 'recentUpdates' => TimelineUpdate::whereHas('timeline', fn($q) => $q->where('user_id', $user->id)) ->latest() ->take(3) ->with('timeline') ->get(), 'pendingBookingsCount' => $user->consultations()->pending()->count(), 'canBookToday' => !$user->consultations() ->whereDate('scheduled_date', today()) ->whereIn('status', ['pending', 'approved']) ->exists(), ]; } }; ?>