reviewd epic 7 stories
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user