reviewd epic 7 stories

This commit is contained in:
Naser Mansour
2025-12-21 00:20:35 +02:00
parent b2977c00d6
commit f6c06ec3e1
5 changed files with 1037 additions and 153 deletions
+223 -51
View File
@@ -1,73 +1,245 @@
# Story 7.3: My Cases/Timelines View
# Story 7.3: My Cases/Timelines View (Dashboard Integration)
## Epic Reference
**Epic 7:** Client Dashboard
## User Story
As a **client**,
I want **to view my case timelines and their updates**,
So that **I can track the progress of my legal matters**.
I want **to access my case timelines from the dashboard navigation**,
So that **I can easily track the progress of my legal matters from one central location**.
## Story Context
### Relationship to Story 4.5
Story 4.5 (`docs/stories/story-4.5-client-timeline-view.md`) already implements the **complete timeline viewing functionality**:
- Routes: `client.timelines.index` and `client.timelines.show`
- Components: `pages/client/timelines/index.blade.php` and `show.blade.php`
- Active/archived separation with visual distinction
- Individual timeline detail view with chronological updates
- Authorization, tests, and translations
**This story (7.3) focuses solely on dashboard navigation integration** - ensuring clients can access the existing timeline views from the Epic 7 client dashboard structure.
### Prerequisites
- **Story 4.5:** Client Timeline View - MUST be complete (provides all timeline components)
- **Story 7.1:** Client Dashboard Overview - MUST be complete (provides dashboard layout and navigation)
### What This Story Does NOT Do
- Does NOT recreate timeline list or detail views (use Story 4.5's components)
- Does NOT add new timeline functionality
- Does NOT modify existing timeline components
## Acceptance Criteria
### Active Cases Section
- [ ] List of active timelines
- [ ] Case name and reference
- [ ] Last update date
- [ ] Update count
- [ ] "View" button
### Navigation Integration
- [ ] "My Cases" navigation item added to client dashboard sidebar/nav
- [ ] Navigation links to `route('client.timelines.index')`
- [ ] Active state shown when on timeline routes
- [ ] Icon: folder or briefcase icon for cases
### Archived Cases Section
- [ ] Clearly separated from active
- [ ] Different visual styling (muted)
- [ ] Still accessible for viewing
### Dashboard Widget (on Story 7.1's dashboard)
- [ ] "My Cases" widget card displays:
- Count of active cases
- Latest update preview (case name + date)
- "View All" link to timeline index
- [ ] Widget shows empty state if no cases exist
### Individual Timeline View
- [ ] Case name and reference
- [ ] Status badge (active/archived)
- [ ] All updates in chronological order
- [ ] Each update shows:
- Date and time
- Update content
- [ ] Read-only (no interactions)
### Layout Consistency
- [ ] Timeline pages use client dashboard layout (consistent header/nav)
- [ ] Breadcrumbs: Dashboard > My Cases (on index)
- [ ] Breadcrumbs: Dashboard > My Cases > [Case Name] (on show)
### Navigation
- [ ] Back to cases list
- [ ] Responsive layout
### Bilingual Support
- [ ] Navigation label translated (AR/EN)
- [ ] Widget content translated (AR/EN)
## Technical Notes
Reuse components from Story 4.5.
### File Structure
```
Files to Modify:
resources/views/components/layouts/client.blade.php (add nav item)
OR resources/views/livewire/pages/client/dashboard.blade.php (add widget)
Files from Story 4.5 (DO NOT MODIFY - just ensure they exist):
resources/views/livewire/pages/client/timelines/index.blade.php
resources/views/livewire/pages/client/timelines/show.blade.php
Tests to Create:
tests/Feature/Client/DashboardTimelineIntegrationTest.php
```
### Navigation Item Addition
Add to client dashboard navigation (location depends on Story 7.1's implementation):
```php
new class extends Component {
public function with(): array
{
return [
'activeTimelines' => auth()->user()
->timelines()
->active()
->withCount('updates')
->latest('updated_at')
->get(),
'archivedTimelines' => auth()->user()
->timelines()
->archived()
->withCount('updates')
->latest('updated_at')
->get(),
];
}
};
{{-- In client layout/navigation component --}}
<flux:navbar.item
href="{{ route('client.timelines.index') }}"
:active="request()->routeIs('client.timelines.*')"
icon="folder"
>
{{ __('client.my_cases') }}
</flux:navbar.item>
```
### Dashboard Widget Component
Add to Story 7.1's dashboard view:
```php
{{-- My Cases Widget --}}
<div class="bg-white rounded-lg shadow-sm p-6">
<div class="flex justify-between items-center mb-4">
<h3 class="font-semibold text-charcoal">{{ __('client.my_cases') }}</h3>
<flux:badge>{{ $activeTimelinesCount }} {{ __('client.active') }}</flux:badge>
</div>
@if($latestTimelineUpdate)
<div class="text-sm text-charcoal/70 mb-4">
<p class="font-medium">{{ $latestTimelineUpdate->timeline->case_name }}</p>
<p class="text-xs">{{ __('client.last_update') }}: {{ $latestTimelineUpdate->created_at->diffForHumans() }}</p>
</div>
@else
<p class="text-sm text-charcoal/50 mb-4">{{ __('client.no_cases_yet') }}</p>
@endif
<flux:button size="sm" href="{{ route('client.timelines.index') }}">
{{ __('client.view_all_cases') }}
</flux:button>
</div>
```
### Data for Widget (add to Story 7.1's dashboard component)
```php
// In dashboard component's with() method
'activeTimelinesCount' => auth()->user()->timelines()->active()->count(),
'latestTimelineUpdate' => TimelineUpdate::whereHas('timeline',
fn($q) => $q->where('user_id', auth()->id())->active()
)
->with('timeline:id,case_name')
->latest()
->first(),
```
### Required Translation Keys
```php
// Add to resources/lang/en/client.php (if not already from 4.5)
'view_all_cases' => 'View All Cases',
// Add to resources/lang/ar/client.php
'view_all_cases' => 'عرض جميع القضايا',
```
## Test Scenarios
```php
<?php
// tests/Feature/Client/DashboardTimelineIntegrationTest.php
use App\Models\{User, Timeline, TimelineUpdate};
test('client dashboard has my cases navigation link', function () {
$client = User::factory()->create(['user_type' => 'individual']);
$this->actingAs($client)
->get(route('client.dashboard'))
->assertOk()
->assertSee(__('client.my_cases'))
->assertSee(route('client.timelines.index'));
});
test('client dashboard shows active cases count in widget', function () {
$client = User::factory()->create(['user_type' => 'individual']);
Timeline::factory()->count(3)->create([
'user_id' => $client->id,
'status' => 'active',
]);
Timeline::factory()->create([
'user_id' => $client->id,
'status' => 'archived',
]);
$this->actingAs($client)
->get(route('client.dashboard'))
->assertSee('3'); // Only active cases counted
});
test('client dashboard shows latest timeline update', function () {
$client = User::factory()->create(['user_type' => 'individual']);
$timeline = Timeline::factory()->create([
'user_id' => $client->id,
'case_name' => 'Property Dispute Case',
]);
TimelineUpdate::factory()->create([
'timeline_id' => $timeline->id,
'created_at' => now(),
]);
$this->actingAs($client)
->get(route('client.dashboard'))
->assertSee('Property Dispute Case');
});
test('client dashboard shows empty state when no cases', function () {
$client = User::factory()->create(['user_type' => 'individual']);
$this->actingAs($client)
->get(route('client.dashboard'))
->assertSee(__('client.no_cases_yet'));
});
test('my cases navigation is active on timeline routes', function () {
$client = User::factory()->create(['user_type' => 'individual']);
$timeline = Timeline::factory()->create(['user_id' => $client->id]);
// Test on index
$this->actingAs($client)
->get(route('client.timelines.index'))
->assertOk();
// Test on show
$this->actingAs($client)
->get(route('client.timelines.show', $timeline))
->assertOk();
});
test('timeline pages use client dashboard layout', function () {
$client = User::factory()->create(['user_type' => 'individual']);
$this->actingAs($client)
->get(route('client.timelines.index'))
->assertSee(__('client.my_cases')); // Nav item visible = layout applied
});
```
## Definition of Done
- [ ] Active cases display correctly
- [ ] Archived cases separated
- [ ] Timeline detail view works
- [ ] Updates display chronologically
- [ ] Read-only enforced
- [ ] Tests pass
- [ ] "My Cases" navigation item added to client dashboard
- [ ] Navigation links to existing `client.timelines.index` route
- [ ] Active state shows on timeline routes
- [ ] Dashboard widget displays active case count
- [ ] Dashboard widget shows latest update preview
- [ ] Dashboard widget links to timeline index
- [ ] Empty state handled in widget
- [ ] Translation keys added for new strings
- [ ] Timeline pages render within client dashboard layout
- [ ] All tests pass
- [ ] Code formatted with Pint
## Dependencies
- **Story 4.5:** Client Timeline View (REQUIRED - provides timeline components and routes)
- **Story 7.1:** Client Dashboard Overview (REQUIRED - provides dashboard layout)
## Notes
This story is intentionally minimal because the heavy lifting was done in Story 4.5. The developer should:
1. Verify Story 4.5 is complete and routes work
2. Add navigation item to client layout
3. Add widget to dashboard
4. Ensure layout consistency
5. Write integration tests
Do NOT duplicate or recreate the timeline components from Story 4.5.
## Estimation
**Complexity:** Medium | **Effort:** 3-4 hours
**Complexity:** Low | **Effort:** 1-2 hours