325 lines
11 KiB
Markdown
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
|