libra/docs/stories/story-15.3-crud-operations.md

378 lines
13 KiB
Markdown

# Story 15.3: CRUD Operations for Potential Clients
## Story
**As an** admin
**I want to** create, view, edit, and delete potential clients
**So that** I can fully manage my prospective client records
## Acceptance Criteria
### AC1: Create Form Access
**Given** the admin is on the potential clients list
**When** clicking "Add Potential Client"
**Then** navigate to `/admin/potential-clients/create`
**And** display the create form
### AC2: Create Form Fields
**Given** the admin is on the create form
**When** the form is displayed
**Then** show the following fields:
- Type (required) - dropdown with Individual, Company, Agency
- Name (optional) - text input
- Phone (optional) - text input
- Email (optional) - email input
- Address (optional) - textarea
- Social Media (optional) - text input (URL or handle)
- Website (optional) - text input (URL)
- Notes (optional) - textarea
### AC3: Create Submission
**Given** the admin fills the create form
**When** submitting with valid data
**Then** create a new potential client record
**And** show success message: "Potential client created successfully" / "تم إنشاء العميل المحتمل بنجاح"
**And** redirect to potential clients list
### AC4: Create Validation
**Given** the admin submits the create form
**When** type is not selected
**Then** show validation error: "Please select a type" / "يرجى اختيار النوع"
**When** email is provided but invalid format
**Then** show validation error on email field
**When** website is provided but invalid URL format
**Then** show validation error on website field
### AC5: View Page
**Given** a potential client exists
**When** the admin clicks the view icon from the list
**Then** navigate to `/admin/potential-clients/{id}`
**And** display all potential client information in a clean layout
**And** show "Edit" and "Delete" action buttons
**And** show "Back to Potential Clients" navigation
### AC6: View Page Display
**Given** the admin is viewing a potential client
**When** the page loads
**Then** display:
- Type with colored badge
- All contact information (showing "Not provided" / "غير متوفر" for empty fields)
- Notes section (if provided)
- Created date
- Last updated date
### AC7: Edit Form Access
**Given** the admin is viewing a potential client
**When** clicking "Edit"
**Then** navigate to `/admin/potential-clients/{id}/edit`
**And** pre-populate form with existing data
**Given** the admin is on the list page
**When** clicking the edit icon
**Then** navigate directly to the edit form
### AC8: Edit Form Submission
**Given** the admin modifies the edit form
**When** submitting with valid data
**Then** update the potential client record
**And** show success message: "Potential client updated successfully" / "تم تحديث العميل المحتمل بنجاح"
**And** redirect to the view page
### AC9: Delete Confirmation
**Given** the admin is viewing a potential client
**When** clicking "Delete"
**Then** show a confirmation modal with:
- Warning message: "Are you sure you want to delete this potential client?" / "هل أنت متأكد من حذف هذا العميل المحتمل؟"
- Potential client name displayed
- "Cancel" and "Delete" buttons
**Given** the admin is on the list page
**When** clicking the delete icon
**Then** show the same confirmation modal
### AC10: Delete Execution
**Given** the delete confirmation modal is shown
**When** the admin confirms deletion
**Then** delete the potential client record
**And** close the modal
**And** show success message: "Potential client deleted successfully" / "تم حذف العميل المحتمل بنجاح"
**And** redirect to list (if on view page) or refresh list (if on list page)
### AC11: RTL Support
**Given** Arabic language is selected
**When** viewing create/edit/view pages
**Then** all forms and layouts align correctly right-to-left
### AC12: Cancel Actions
**Given** the admin is on create or edit form
**When** clicking "Cancel"
**Then** navigate back to the previous page (list or view)
**And** discard unsaved changes
## Technical Notes
### Files to Create
| File | Purpose |
|------|---------|
| `resources/views/livewire/admin/potential-clients/create.blade.php` | Create form component |
| `resources/views/livewire/admin/potential-clients/show.blade.php` | View page component |
| `resources/views/livewire/admin/potential-clients/edit.blade.php` | Edit form component |
### Files to Modify
| File | Change |
|------|--------|
| `routes/web.php` | Add create, show, edit routes |
| `resources/views/livewire/admin/potential-clients/index.blade.php` | Add delete modal |
| `lang/en/potential-clients.php` | Add CRUD translations |
| `lang/ar/potential-clients.php` | Add CRUD translations |
### Routes
```php
// Add to admin routes group
Route::get('/admin/potential-clients/create', /* component */)->name('admin.potential-clients.create');
Route::get('/admin/potential-clients/{potentialClient}', /* component */)->name('admin.potential-clients.show');
Route::get('/admin/potential-clients/{potentialClient}/edit', /* component */)->name('admin.potential-clients.edit');
```
### Create Component Structure
```php
<?php
use App\Enums\PotentialClientType;
use App\Models\PotentialClient;
use Livewire\Volt\Component;
new class extends Component {
public string $type = '';
public string $name = '';
public string $phone = '';
public string $email = '';
public string $address = '';
public string $social_media = '';
public string $website = '';
public string $notes = '';
public function rules(): array
{
return [
'type' => ['required', 'in:individual,company,agency'],
'name' => ['nullable', 'string', 'max:255'],
'phone' => ['nullable', 'string', 'max:50'],
'email' => ['nullable', 'email', 'max:255'],
'address' => ['nullable', 'string', 'max:1000'],
'social_media' => ['nullable', 'string', 'max:255'],
'website' => ['nullable', 'url', 'max:255'],
'notes' => ['nullable', 'string', 'max:5000'],
];
}
public function create(): void
{
$validated = $this->validate();
PotentialClient::create($validated);
session()->flash('success', __('potential-clients.created_success'));
$this->redirect(route('admin.potential-clients.index'), navigate: true);
}
public function with(): array
{
return [
'types' => PotentialClientType::cases(),
];
}
}; ?>
```
### Show Component Structure
```php
<?php
use App\Models\PotentialClient;
use Livewire\Volt\Component;
new class extends Component {
public PotentialClient $potentialClient;
public bool $showDeleteModal = false;
public function confirmDelete(): void
{
$this->showDeleteModal = true;
}
public function delete(): void
{
$this->potentialClient->delete();
session()->flash('success', __('potential-clients.deleted_success'));
$this->redirect(route('admin.potential-clients.index'), navigate: true);
}
}; ?>
```
### Additional Translations
```php
// Add to lang/en/potential-clients.php
'create_potential_client' => 'Create Potential Client',
'edit_potential_client' => 'Edit Potential Client',
'potential_client_details' => 'Potential Client Details',
'back_to_list' => 'Back to Potential Clients',
'not_provided' => 'Not provided',
'created_success' => 'Potential client created successfully',
'updated_success' => 'Potential client updated successfully',
'deleted_success' => 'Potential client deleted successfully',
'delete_confirm_title' => 'Delete Potential Client',
'delete_confirm_message' => 'Are you sure you want to delete this potential client?',
'cancel' => 'Cancel',
'save' => 'Save',
'create' => 'Create',
'contact_information' => 'Contact Information',
'additional_information' => 'Additional Information',
'type_required' => 'Please select a type',
// Add to lang/ar/potential-clients.php
'create_potential_client' => 'إنشاء عميل محتمل',
'edit_potential_client' => 'تعديل العميل المحتمل',
'potential_client_details' => 'تفاصيل العميل المحتمل',
'back_to_list' => 'العودة للقائمة',
'not_provided' => 'غير متوفر',
'created_success' => 'تم إنشاء العميل المحتمل بنجاح',
'updated_success' => 'تم تحديث العميل المحتمل بنجاح',
'deleted_success' => 'تم حذف العميل المحتمل بنجاح',
'delete_confirm_title' => 'حذف العميل المحتمل',
'delete_confirm_message' => 'هل أنت متأكد من حذف هذا العميل المحتمل؟',
'cancel' => 'إلغاء',
'save' => 'حفظ',
'create' => 'إنشاء',
'contact_information' => 'معلومات الاتصال',
'additional_information' => 'معلومات إضافية',
'type_required' => 'يرجى اختيار النوع',
```
### Delete Modal (using Flux)
```blade
<flux:modal name="delete-potential-client" class="min-w-[22rem]">
<div class="space-y-6">
<div>
<flux:heading size="lg">{{ __('potential-clients.delete_confirm_title') }}</flux:heading>
<flux:text class="mt-2">{{ __('potential-clients.delete_confirm_message') }}</flux:text>
<flux:text class="mt-2 font-medium">{{ $potentialClient->name ?? __('potential-clients.not_provided') }}</flux:text>
</div>
<div class="flex gap-2">
<flux:spacer />
<flux:button variant="ghost" x-on:click="$flux.modal('delete-potential-client').close()">
{{ __('potential-clients.cancel') }}
</flux:button>
<flux:button variant="danger" wire:click="delete">
{{ __('potential-clients.delete') }}
</flux:button>
</div>
</div>
</flux:modal>
```
## Dev Checklist
- [x] Add routes for create, show, edit pages
- [x] Create `create.blade.php` component with form
- [x] Create `show.blade.php` component with details display
- [x] Create `edit.blade.php` component with pre-populated form
- [x] Add delete confirmation modal to show page
- [x] Add delete functionality to list page (inline delete)
- [x] Implement form validation rules
- [x] Add success flash messages
- [x] Add English translations for CRUD operations
- [x] Add Arabic translations for CRUD operations
- [x] Test create flow
- [x] Test edit flow
- [x] Test delete flow
- [x] Test validation errors
- [x] Test RTL layout
- [x] Write feature tests for all CRUD operations
## Estimation
**Complexity:** Medium
**Risk:** Low - Follows established patterns
## Dependencies
- Story 15.1 (Database & Model) must be completed
- Story 15.2 (List & Filter) must be completed
---
## Dev Agent Record
### Status
**Ready for Review**
### Agent Model Used
Claude Opus 4.5 (claude-opus-4-5-20251101)
### File List
| File | Action |
|------|--------|
| `routes/web.php` | Modified - Added create, show, edit routes for potential clients |
| `resources/views/livewire/admin/potential-clients/create.blade.php` | Created - Create form component |
| `resources/views/livewire/admin/potential-clients/show.blade.php` | Created - View page component with delete modal |
| `resources/views/livewire/admin/potential-clients/edit.blade.php` | Created - Edit form component |
| `resources/views/livewire/admin/potential-clients/index.blade.php` | Modified - Added delete modal and updated action buttons |
| `lang/en/potential-clients.php` | Modified - Added CRUD translations |
| `lang/ar/potential-clients.php` | Modified - Added CRUD translations |
| `tests/Feature/Admin/PotentialClientCrudTest.php` | Created - 38 feature tests for CRUD operations |
### Change Log
- Added routes for `/admin/potential-clients/create`, `/admin/potential-clients/{potentialClient}`, `/admin/potential-clients/{potentialClient}/edit`
- Created create component with type dropdown, contact fields, and validation
- Created show component displaying all client info with type badge, contact info, notes, and timestamps
- Created edit component with pre-populated form fields
- Added delete confirmation modal to both show and index pages
- Implemented form validation: type required, email format, URL format, max lengths
- Added 23 new translation keys for English and Arabic
- Created 38 comprehensive feature tests covering:
- Create page access and form submission
- Show page access and display
- Edit page access, pre-population, and submission
- Delete from show and index pages
- All validation scenarios
- Navigation links
### Debug Log References
N/A - No debug issues encountered
### Completion Notes
- All 72 potential client tests pass (38 CRUD + 21 List + 13 Unit)
- Follows existing patterns from individual/company client management
- RTL support handled through existing Flux components and Tailwind
- Pre-existing AccessibilityComplianceTest failure is unrelated to these changes