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

325 lines
11 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
- [ ] Add routes for create, show, edit pages
- [ ] Create `create.blade.php` component with form
- [ ] Create `show.blade.php` component with details display
- [ ] Create `edit.blade.php` component with pre-populated form
- [ ] Add delete confirmation modal to show page
- [ ] Add delete functionality to list page (inline delete)
- [ ] Implement form validation rules
- [ ] Add success flash messages
- [ ] Add English translations for CRUD operations
- [ ] Add Arabic translations for CRUD operations
- [ ] Test create flow
- [ ] Test edit flow
- [ ] Test delete flow
- [ ] Test validation errors
- [ ] Test RTL layout
- [ ] 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