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

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 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:

// 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

  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

.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