13 KiB
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
// 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
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
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
// 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)
<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.phpcomponent with form - Create
show.blade.phpcomponent with details display - Create
edit.blade.phpcomponent 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
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