import type { Contact } from '~/modules/directory/services/dto/contact' import type { Address } from '~/modules/directory/services/dto/address' import { useContactService } from '~/modules/directory/services/contacts' import { useAddressService } from '~/modules/directory/services/addresses' type Owner = { client?: string, prospect?: string } /** * Logique partagée des fiches détail Client/Prospect : blocs répétables Contact * et Adresse (chargement, ajout, suppression). L'édition est tenue en mémoire * localement ; la persistance se fait au clic sur « Enregistrer » (saveContacts/ * saveAddresses), comme les formulaires de tâche — pas d'enregistrement au blur. * Paramétré par l'IRI du propriétaire (`{ client }` ou `{ prospect }`), réutilisé * tel quel par les deux pages. */ export function useDirectoryDetail(owner: Owner) { const contactService = useContactService() const addressService = useAddressService() const contacts = ref([]) const addresses = ref([]) const savingContacts = ref(false) const savingAddresses = ref(false) function emptyContact(): Contact { return { id: 0, firstName: null, lastName: null, jobTitle: null, email: null, phonePrimary: null, phoneSecondary: null, ...owner } } function emptyAddress(): Address { return { id: 0, label: null, street: null, streetComplement: null, postalCode: null, city: null, country: 'FR', ...owner } } // Édition locale uniquement : on remplace le bloc en mémoire, rien n'est // persisté tant que l'utilisateur n'a pas cliqué sur « Enregistrer ». function onContactInput(index: number, value: Contact): void { contacts.value[index] = value } function onAddressInput(index: number, value: Address): void { addresses.value[index] = value } function addContact(): void { contacts.value.push(emptyContact()) } function addAddress(): void { addresses.value.push(emptyAddress()) } // Suppression immédiate (comme la corbeille du formulaire de tâche) : un bloc // déjà enregistré est supprimé côté serveur, une amorce non enregistrée est // simplement retirée de la liste. async function removeContact(index: number): Promise { const c = contacts.value[index] if (c?.id && c.id > 0) await contactService.remove(c.id) contacts.value.splice(index, 1) } async function removeAddress(index: number): Promise { const a = addresses.value[index] if (a?.id && a.id > 0) await addressService.remove(a.id) addresses.value.splice(index, 1) } // Persistance au clic : met à jour les blocs existants, crée les nouveaux // blocs renseignés. Les amorces vides (sans contenu) sont ignorées. async function saveContacts(): Promise { if (savingContacts.value) return savingContacts.value = true try { for (let i = 0; i < contacts.value.length; i++) { const c = contacts.value[i] if (!c) continue const payload = { firstName: c.firstName, lastName: c.lastName, jobTitle: c.jobTitle, email: c.email, phonePrimary: c.phonePrimary, phoneSecondary: c.phoneSecondary, ...owner } if (c.id && c.id > 0) { contacts.value[i] = await contactService.update(c.id, payload) } else if (c.lastName || c.firstName) { contacts.value[i] = await contactService.create(payload) } } } finally { savingContacts.value = false } } async function saveAddresses(): Promise { if (savingAddresses.value) return savingAddresses.value = true try { for (let i = 0; i < addresses.value.length; i++) { const a = addresses.value[i] if (!a) continue const payload = { label: a.label, street: a.street, streetComplement: a.streetComplement, postalCode: a.postalCode, city: a.city, country: a.country, ...owner } if (a.id && a.id > 0) { addresses.value[i] = await addressService.update(a.id, payload) } else if (a.street || a.city || a.postalCode) { addresses.value[i] = await addressService.create(payload) } } } finally { savingAddresses.value = false } } async function load(): Promise { contacts.value = await contactService.getByOwner(owner) addresses.value = await addressService.getByOwner(owner) } return { contacts, addresses, savingContacts, savingAddresses, onContactInput, addContact, removeContact, saveContacts, onAddressInput, addAddress, removeAddress, saveAddresses, load, } }