New-Thanasoft/thanasoft-front/CLIENT_CREATION_FLOW.md
2025-10-09 18:25:02 +03:00

272 lines
6.9 KiB
Markdown

# 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:**
```vue
<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 store
- `validationErrors`: Object - validation errors from API
- `success`: 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:**
```vue
// 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:**
```vue
<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
```php
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)
```json
{
"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:
```json
{
"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
1. **User fills the form**
- All fields are validated client-side (maxlength, email format)
2. **User clicks "Créer le client"**
- Button shows loading spinner
- Button is disabled
- Previous errors are cleared
3. **If validation fails (422)**
- Errors appear below each invalid field in red
- Loading stops
- Button is re-enabled
- User can fix errors and resubmit
4. **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
```css
.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