From 925ffc9c3fd9b36b1d95838f9bcc57c602748871 Mon Sep 17 00:00:00 2001 From: louispaulb Date: Sat, 4 Jul 2026 21:31:33 -0400 Subject: [PATCH] refactor(ops): extract LocationCard from ClientDetailPage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit T7 découpage géants — sort le « lieu de service » (en-tête adresse + DeviceStrip + abonnements mensuels/annuels drag-drop + tickets) dans components/customer/LocationCard.vue. Les sélecteurs/actions stateful (locSubs*/toggle*/onSub*/section*) restent liés aux instances de composables du parent et sont passés en props-fonctions homonymes → le template les résout inchangé, comportement identique (mêmes closures, même invalidation de cache useSubscriptionGroups/useSubscriptionActions). Helpers purs (formatMoney/isRebate/…) et usePermissions importés dans l'enfant. Styles loc-*/sub-* copiés (scoped). ClientDetailPage -242 l. ; imports morts retirés (DeviceStrip/locStatusClass/isRebate/subMainLabel/ sectionTotal/annualPrice/locInlineFields). Vérifié en local sur hub LIVE (C-LPB4) : rendu pixel-identique (carte 691 rue des hirondelles, DeviceStrip live acs-online, ABONNEMENTS 4 = INTERNET 3 / RABAIS 1, total 0,00 $/m), toggle de section fonctionne via la prop (INTERNET 0→3 rangées, chevron expand_more), 0 erreur console. Co-Authored-By: Claude Opus 4.8 --- .../src/components/customer/LocationCard.vue | 401 ++++++++++++++++++ apps/ops/src/pages/ClientDetailPage.vue | 314 ++------------ 2 files changed, 437 insertions(+), 278 deletions(-) create mode 100644 apps/ops/src/components/customer/LocationCard.vue diff --git a/apps/ops/src/components/customer/LocationCard.vue b/apps/ops/src/components/customer/LocationCard.vue new file mode 100644 index 0000000..2aa999f --- /dev/null +++ b/apps/ops/src/components/customer/LocationCard.vue @@ -0,0 +1,401 @@ + + + + + diff --git a/apps/ops/src/pages/ClientDetailPage.vue b/apps/ops/src/pages/ClientDetailPage.vue index 7027980..afcef0d 100644 --- a/apps/ops/src/pages/ClientDetailPage.vue +++ b/apps/ops/src/pages/ClientDetailPage.vue @@ -70,280 +70,38 @@
Aucun lieu de service
-
-
-
-
- -
-
-
- -
-
- - -
-
-
- - {{ formatMoney(locSubsMonthlyTotal(loc.name)) }}/m - - - {{ locHasSubs(loc.name) ? loc.status : 'Inactif' }} - - - Supprimer cette adresse - -
-
-
- -
- -
-
- - - · OLT: - · -
- -
- -
-
- Abonnements ({{ locSubs(loc.name).length }}) - - Ajouter un service - - - - - - Nouvelle soumission - Wizard avec étapes - - - - - - Forfait / Service (direct) - - - - Rabais / Crédit - - - - -
-
Aucun
- - - - -
- -
-
- Tickets ({{ locTickets(loc.name).length }}) - - Créer un ticket pour cette adresse - -
-
-
- -
- {{ t.legacy_ticket_id || t.name }} - {{ t.subject }} -
-
- - {{ staffInitials(t.opened_by_staff) }} - {{ t.opened_by_staff }} - - - {{ staffInitials(t.assigned_staff) }} - {{ t.assigned_staff }} - -
- {{ t.opening_date }} - {{ t.status }} -
-
-
- -
-
+
@@ -1061,9 +819,9 @@ import { authFetch } from 'src/api/auth' import { BASE_URL, ERP_DESK_URL } from 'src/config/erpnext' import { HUB_URL } from 'src/config/hub' import { formatDate, formatDateTime, formatMoney, staffColor, staffInitials, noteAuthorName } from 'src/composables/useFormatters' -import { locStatusClass, ticketStatusClass, invStatusClass, priorityClass } from 'src/composables/useStatusClasses' +import { ticketStatusClass, invStatusClass, priorityClass } from 'src/composables/useStatusClasses' import { useDetailModal } from 'src/composables/useDetailModal' -import { useSubscriptionGroups, isRebate, subMainLabel, sectionTotal, annualPrice } from 'src/composables/useSubscriptionGroups' +import { useSubscriptionGroups } from 'src/composables/useSubscriptionGroups' import { useSubscriptionActions } from 'src/composables/useSubscriptionActions' import { useCustomerNotes } from 'src/composables/useCustomerNotes' import { useConversations } from 'src/composables/useConversations' @@ -1085,11 +843,11 @@ import { usePermissions } from 'src/composables/usePermissions' import { usePaymentActions } from 'src/composables/usePaymentActions' import { useClientData } from 'src/composables/useClientData' import { useEquipmentActions } from 'src/composables/useEquipmentActions' -import { locInlineFields, equipTypeOptions, equipStatusOptions, defaultSectionsOpen, phoneLabelMap, CLIENT_360_MODULES } from 'src/data/client-constants' +import { equipTypeOptions, equipStatusOptions, defaultSectionsOpen, phoneLabelMap, CLIENT_360_MODULES } from 'src/data/client-constants' import { useUserPrefs } from 'src/composables/useUserPrefs' import { erpPdfUrl } from 'src/utils/erp-pdf' import RewardDialog from 'src/components/customer/RewardDialog.vue' -import DeviceStrip from 'src/components/customer/DeviceStrip.vue' +import LocationCard from 'src/components/customer/LocationCard.vue' const $q = useQuasar() const { can } = usePermissions()