6.9 KiB
6.9 KiB
Client Creation Flow - Complete Implementation
Overview
Complete implementation of the client creation feature with:
- ✅ Form validation
- ✅ Error handling (Laravel validation errors)
- ✅ Loading states
- ✅ Success messages
- ✅ Auto-redirect after success
- ✅ Store integration
Data Flow
AddClient.vue (Page)
↓ (passes props & handles events)
AddClientPresentation.vue (Organism)
↓ (passes props & emits)
NewClientForm.vue (Form Component)
↓ (user fills form & clicks submit)
↑ (emits createClient event)
AddClient.vue (receives event)
↓ (calls store)
clientStore.createClient()
↓ (API call)
Laravel ClientController
↓ (validates with StoreClientRequest)
↓ (creates client or returns 422 errors)
↑ (returns success or validation errors)
AddClient.vue (handles response)
↓ (passes validation errors back to form)
NewClientForm.vue (displays errors under inputs)
Components Updated
1. AddClient.vue (Page Component)
Location: src/views/pages/CRM/AddClient.vue
Responsibilities:
- Fetch client categories on mount
- Handle form submission via
handleCreateClient - Call store to create client
- Handle validation errors from API (422 status)
- Show success message
- Redirect to clients list after success
Key Code:
<script setup>
const handleCreateClient = async (form) => {
try {
validationErrors.value = {};
showSuccess.value = false;
const client = await clientStore.createClient(form);
showSuccess.value = true;
setTimeout(() => {
router.push({ name: 'Clients' });
}, 2000);
} catch (error) {
if (error.response && error.response.status === 422) {
validationErrors.value = error.response.data.errors || {};
}
}
};
</script>
2. AddClientPresentation.vue (Organism)
Location: src/components/Organism/CRM/AddClientPresentation.vue
Responsibilities:
- Pass props to NewClientForm
- Relay events from form to parent
Props Added:
loading: Boolean - loading state from storevalidationErrors: Object - validation errors from APIsuccess: Boolean - success state
3. NewClientForm.vue (Form Component)
Location: src/components/molecules/form/NewClientForm.vue
Responsibilities:
- Display form fields with proper validation styling
- Watch for validation errors from parent
- Display errors below each input
- Show loading spinner on button
- Show success alert
- Emit createClient event with form data
- Reset form on success
Key Features:
// Watch for validation errors
watch(() => props.validationErrors, (newErrors) => {
fieldErrors.value = { ...newErrors };
}, { deep: true });
// Watch for success
watch(() => props.success, (newSuccess) => {
if (newSuccess) {
resetForm();
}
});
// Submit form
const submitForm = async () => {
fieldErrors.value = {};
errors.value = [];
emit("createClient", form);
};
Validation Error Display:
<soft-input
v-model="form.name"
:class="{ 'is-invalid': fieldErrors.name }"
type="text"
/>
<div v-if="fieldErrors.name" class="invalid-feedback">
{{ fieldErrors.name }}
</div>
Laravel Backend
StoreClientRequest Validation Rules
public function rules(): array
{
return [
'client_category_id' => 'nullable',
'name' => 'required|string|max:255',
'vat_number' => 'nullable|string|max:32',
'siret' => 'nullable|string|max:20',
'email' => 'nullable|email|max:191',
'phone' => 'nullable|string|max:50',
'billing_address_line1' => 'nullable|string|max:255',
'billing_address_line2' => 'nullable|string|max:255',
'billing_postal_code' => 'nullable|string|max:20',
'billing_city' => 'nullable|string|max:191',
'billing_country_code' => 'nullable|string|size:2',
'group_id' => 'nullable|exists:client_groups,id',
'notes' => 'nullable|string',
'is_active' => 'boolean',
'default_tva_rate_id' => 'nullable|exists:tva_rates,id',
];
}
Test Data (Postman)
{
"client_category_id": 1,
"name": "SARL TechnoPlus",
"vat_number": "FR98765432109",
"siret": "98765432100019",
"email": "compta@technoplus.fr",
"phone": "+33198765432",
"billing_address_line1": "789 Boulevard Haussmann",
"billing_postal_code": "75009",
"billing_city": "Paris",
"billing_country_code": "FR",
"notes": "Nouveau client entreprise",
"is_active": true
}
Error Handling
Validation Errors (422)
When Laravel returns validation errors:
{
"message": "The given data was invalid.",
"errors": {
"name": ["Le nom du client est obligatoire."],
"email": ["L'adresse email doit être valide."]
}
}
These are automatically displayed below each input field.
Server Errors (500)
When server error occurs:
- Alert is shown with error message
- User can retry
Network Errors
When network is unavailable:
- Alert is shown with generic error message
User Experience Flow
-
User fills the form
- All fields are validated client-side (maxlength, email format)
-
User clicks "Créer le client"
- Button shows loading spinner
- Button is disabled
- Previous errors are cleared
-
If validation fails (422)
- Errors appear below each invalid field in red
- Loading stops
- Button is re-enabled
- User can fix errors and resubmit
-
If creation succeeds
- Success message appears in green
- Form is reset
- After 2 seconds, user is redirected to clients list
Required Fields
Only name is required. All other fields are optional.
- ✅ Name: Required (max 255 chars)
- ⭕ Email: Optional but must be valid email format
- ⭕ VAT Number: Optional (max 32 chars)
- ⭕ SIRET: Optional (max 20 chars)
- ⭕ Phone: Optional (max 50 chars)
- ⭕ Address fields: Optional
- ⭕ Country code: Optional (must be 2 chars if provided)
- ⭕ Notes: Optional
- ✅ Active status: Defaults to true
CSS Classes for Validation
.is-invalid {
border-color: #f5365c !important;
}
.invalid-feedback {
display: block;
color: #f5365c;
font-size: 0.875rem;
margin-top: 0.25rem;
}
Testing Checklist
- Submit empty form → "name" required error shows
- Submit with invalid email → email validation error shows
- Submit with VAT > 32 chars → VAT length error shows
- Submit with SIRET > 20 chars → SIRET length error shows
- Submit valid data → Success message & redirect
- Check loading spinner appears during submission
- Check button is disabled during submission
- Check form resets after success
- Check redirect happens after 2 seconds
Future Enhancements
- Add client category dropdown (currently just ID)
- Add client group dropdown
- Add TVA rate dropdown
- Add real-time validation as user types
- Add confirmation modal before submit
- Add ability to create contact at same time
- Add file upload for documents