@open-mercato/core 0.5.1-develop.2663.2c29774b5b → 0.5.1-develop.2681.c559bb2bc3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (687) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/generated/entities/action_log/index.js +8 -0
  3. package/dist/generated/entities/action_log/index.js.map +2 -2
  4. package/dist/generated/entities/customer_company_billing/index.js +23 -0
  5. package/dist/generated/entities/customer_company_billing/index.js.map +7 -0
  6. package/dist/generated/entities/customer_deal/index.js +8 -0
  7. package/dist/generated/entities/customer_deal/index.js.map +2 -2
  8. package/dist/generated/entities/customer_deal_stage_transition/index.js +31 -0
  9. package/dist/generated/entities/customer_deal_stage_transition/index.js.map +7 -0
  10. package/dist/generated/entities/customer_dictionary_kind_setting/index.js +21 -0
  11. package/dist/generated/entities/customer_dictionary_kind_setting/index.js.map +7 -0
  12. package/dist/generated/entities/customer_entity/index.js +8 -0
  13. package/dist/generated/entities/customer_entity/index.js.map +2 -2
  14. package/dist/generated/entities/customer_entity_role/index.js +23 -0
  15. package/dist/generated/entities/customer_entity_role/index.js.map +7 -0
  16. package/dist/generated/entities/customer_interaction/index.js +23 -1
  17. package/dist/generated/entities/customer_interaction/index.js.map +2 -2
  18. package/dist/generated/entities/customer_label/index.js +19 -0
  19. package/dist/generated/entities/customer_label/index.js.map +7 -0
  20. package/dist/generated/entities/customer_label_assignment/index.js +17 -0
  21. package/dist/generated/entities/customer_label_assignment/index.js.map +7 -0
  22. package/dist/generated/entities/customer_person_company_link/index.js +21 -0
  23. package/dist/generated/entities/customer_person_company_link/index.js.map +7 -0
  24. package/dist/generated/entities/customer_person_company_role/index.js +17 -0
  25. package/dist/generated/entities/customer_person_company_role/index.js.map +7 -0
  26. package/dist/generated/entities/dictionary_entry/index.js +4 -0
  27. package/dist/generated/entities/dictionary_entry/index.js.map +2 -2
  28. package/dist/generated/entities.ids.generated.js +9 -1
  29. package/dist/generated/entities.ids.generated.js.map +2 -2
  30. package/dist/generated/entity-fields-registry.js +116 -1
  31. package/dist/generated/entity-fields-registry.js.map +2 -2
  32. package/dist/modules/attachments/api/route.js +46 -8
  33. package/dist/modules/attachments/api/route.js.map +2 -2
  34. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js +208 -0
  35. package/dist/modules/audit_logs/api/audit-logs/actions/export/route.js.map +7 -0
  36. package/dist/modules/audit_logs/api/audit-logs/actions/route.js +52 -6
  37. package/dist/modules/audit_logs/api/audit-logs/actions/route.js.map +2 -2
  38. package/dist/modules/audit_logs/cli.js +62 -0
  39. package/dist/modules/audit_logs/cli.js.map +7 -0
  40. package/dist/modules/audit_logs/data/entities.js +21 -1
  41. package/dist/modules/audit_logs/data/entities.js.map +2 -2
  42. package/dist/modules/audit_logs/data/validators.js +9 -1
  43. package/dist/modules/audit_logs/data/validators.js.map +2 -2
  44. package/dist/modules/audit_logs/lib/changeRows.js +34 -0
  45. package/dist/modules/audit_logs/lib/changeRows.js.map +7 -0
  46. package/dist/modules/audit_logs/lib/display-helpers.js +2 -20
  47. package/dist/modules/audit_logs/lib/display-helpers.js.map +3 -3
  48. package/dist/modules/audit_logs/lib/projections.js +58 -0
  49. package/dist/modules/audit_logs/lib/projections.js.map +7 -0
  50. package/dist/modules/audit_logs/migrations/Migration20260412160533.js +21 -0
  51. package/dist/modules/audit_logs/migrations/Migration20260412160533.js.map +7 -0
  52. package/dist/modules/audit_logs/services/actionLogService.js +313 -79
  53. package/dist/modules/audit_logs/services/actionLogService.js.map +2 -2
  54. package/dist/modules/customers/acl.js +3 -1
  55. package/dist/modules/customers/acl.js.map +2 -2
  56. package/dist/modules/customers/api/activities/route.js +4 -0
  57. package/dist/modules/customers/api/activities/route.js.map +2 -2
  58. package/dist/modules/customers/api/assignable-staff/route.js +208 -0
  59. package/dist/modules/customers/api/assignable-staff/route.js.map +7 -0
  60. package/dist/modules/customers/api/companies/[id]/people/route.js +205 -0
  61. package/dist/modules/customers/api/companies/[id]/people/route.js.map +7 -0
  62. package/dist/modules/customers/api/companies/[id]/roles/route.js +22 -0
  63. package/dist/modules/customers/api/companies/[id]/roles/route.js.map +7 -0
  64. package/dist/modules/customers/api/companies/[id]/route.js +374 -32
  65. package/dist/modules/customers/api/companies/[id]/route.js.map +2 -2
  66. package/dist/modules/customers/api/companies/route.js +82 -7
  67. package/dist/modules/customers/api/companies/route.js.map +2 -2
  68. package/dist/modules/customers/api/deals/[id]/companies/route.js +172 -0
  69. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +7 -0
  70. package/dist/modules/customers/api/deals/[id]/people/route.js +156 -0
  71. package/dist/modules/customers/api/deals/[id]/people/route.js.map +7 -0
  72. package/dist/modules/customers/api/deals/[id]/route.js +459 -53
  73. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  74. package/dist/modules/customers/api/deals/[id]/stats/route.js +195 -0
  75. package/dist/modules/customers/api/deals/[id]/stats/route.js.map +7 -0
  76. package/dist/modules/customers/api/deals/route.js +20 -10
  77. package/dist/modules/customers/api/deals/route.js.map +3 -3
  78. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +105 -4
  79. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
  80. package/dist/modules/customers/api/dictionaries/[kind]/route.js +118 -42
  81. package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
  82. package/dist/modules/customers/api/dictionaries/context.js +30 -6
  83. package/dist/modules/customers/api/dictionaries/context.js.map +2 -2
  84. package/dist/modules/customers/api/dictionaries/kind-settings/route.js +207 -0
  85. package/dist/modules/customers/api/dictionaries/kind-settings/route.js.map +7 -0
  86. package/dist/modules/customers/api/entity-roles-factory.js +471 -0
  87. package/dist/modules/customers/api/entity-roles-factory.js.map +7 -0
  88. package/dist/modules/customers/api/interactions/conflicts/route.js +158 -0
  89. package/dist/modules/customers/api/interactions/conflicts/route.js.map +7 -0
  90. package/dist/modules/customers/api/interactions/counts/route.js +92 -0
  91. package/dist/modules/customers/api/interactions/counts/route.js.map +7 -0
  92. package/dist/modules/customers/api/interactions/route.js +83 -4
  93. package/dist/modules/customers/api/interactions/route.js.map +2 -2
  94. package/dist/modules/customers/api/labels/assign/route.js +189 -0
  95. package/dist/modules/customers/api/labels/assign/route.js.map +7 -0
  96. package/dist/modules/customers/api/labels/auth.js +17 -0
  97. package/dist/modules/customers/api/labels/auth.js.map +7 -0
  98. package/dist/modules/customers/api/labels/route.js +281 -0
  99. package/dist/modules/customers/api/labels/route.js.map +7 -0
  100. package/dist/modules/customers/api/labels/table-errors.js +38 -0
  101. package/dist/modules/customers/api/labels/table-errors.js.map +7 -0
  102. package/dist/modules/customers/api/labels/unassign/route.js +184 -0
  103. package/dist/modules/customers/api/labels/unassign/route.js.map +7 -0
  104. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +292 -0
  105. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +7 -0
  106. package/dist/modules/customers/api/people/[id]/companies/context.js +66 -0
  107. package/dist/modules/customers/api/people/[id]/companies/context.js.map +7 -0
  108. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +334 -0
  109. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +7 -0
  110. package/dist/modules/customers/api/people/[id]/companies/route.js +205 -0
  111. package/dist/modules/customers/api/people/[id]/companies/route.js.map +7 -0
  112. package/dist/modules/customers/api/people/[id]/roles/route.js +22 -0
  113. package/dist/modules/customers/api/people/[id]/roles/route.js.map +7 -0
  114. package/dist/modules/customers/api/people/[id]/route.js +134 -21
  115. package/dist/modules/customers/api/people/[id]/route.js.map +2 -2
  116. package/dist/modules/customers/api/people/route.js +122 -23
  117. package/dist/modules/customers/api/people/route.js.map +2 -2
  118. package/dist/modules/customers/api/todos/route.js +4 -0
  119. package/dist/modules/customers/api/todos/route.js.map +2 -2
  120. package/dist/modules/customers/api/utils.js +22 -0
  121. package/dist/modules/customers/api/utils.js.map +2 -2
  122. package/dist/modules/customers/backend/config/customers/page.js +2 -6
  123. package/dist/modules/customers/backend/config/customers/page.js.map +2 -2
  124. package/dist/modules/customers/backend/customers/companies/page.js +37 -26
  125. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  126. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +265 -262
  127. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +3 -3
  128. package/dist/modules/customers/backend/customers/deals/[id]/hooks/formatters.js +23 -0
  129. package/dist/modules/customers/backend/customers/deals/[id]/hooks/formatters.js.map +7 -0
  130. package/dist/modules/customers/backend/customers/deals/[id]/hooks/types.js +1 -0
  131. package/dist/modules/customers/backend/customers/deals/[id]/hooks/types.js.map +7 -0
  132. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js +43 -0
  133. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.js.map +7 -0
  134. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js +264 -0
  135. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.js.map +7 -0
  136. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js +88 -0
  137. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.js.map +7 -0
  138. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js +41 -0
  139. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealData.js.map +7 -0
  140. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +66 -0
  141. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +7 -0
  142. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js +39 -0
  143. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.js.map +7 -0
  144. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.js +49 -0
  145. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.js.map +7 -0
  146. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js +43 -0
  147. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.js.map +7 -0
  148. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.js +28 -0
  149. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.js.map +7 -0
  150. package/dist/modules/customers/backend/customers/deals/[id]/page.js +556 -503
  151. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +3 -3
  152. package/dist/modules/customers/backend/customers/deals/page.js +66 -21
  153. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  154. package/dist/modules/customers/backend/customers/people/page.js +36 -28
  155. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  156. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +318 -203
  157. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +3 -3
  158. package/dist/modules/customers/cli.js +105 -13
  159. package/dist/modules/customers/cli.js.map +2 -2
  160. package/dist/modules/customers/commands/activities.js +6 -0
  161. package/dist/modules/customers/commands/activities.js.map +2 -2
  162. package/dist/modules/customers/commands/deals.js +315 -107
  163. package/dist/modules/customers/commands/deals.js.map +2 -2
  164. package/dist/modules/customers/commands/dictionaries.js +166 -32
  165. package/dist/modules/customers/commands/dictionaries.js.map +2 -2
  166. package/dist/modules/customers/commands/dictionaryKindSettings.js +208 -0
  167. package/dist/modules/customers/commands/dictionaryKindSettings.js.map +7 -0
  168. package/dist/modules/customers/commands/entity-roles.js +415 -0
  169. package/dist/modules/customers/commands/entity-roles.js.map +7 -0
  170. package/dist/modules/customers/commands/index.js +4 -0
  171. package/dist/modules/customers/commands/index.js.map +2 -2
  172. package/dist/modules/customers/commands/interactions.js +108 -21
  173. package/dist/modules/customers/commands/interactions.js.map +2 -2
  174. package/dist/modules/customers/commands/labels.js +539 -0
  175. package/dist/modules/customers/commands/labels.js.map +7 -0
  176. package/dist/modules/customers/commands/people.js +560 -463
  177. package/dist/modules/customers/commands/people.js.map +3 -3
  178. package/dist/modules/customers/commands/personCompanyLinks.js +568 -0
  179. package/dist/modules/customers/commands/personCompanyLinks.js.map +7 -0
  180. package/dist/modules/customers/commands/shared.js +12 -4
  181. package/dist/modules/customers/commands/shared.js.map +2 -2
  182. package/dist/modules/customers/commands/todos.js +10 -1
  183. package/dist/modules/customers/commands/todos.js.map +2 -2
  184. package/dist/modules/customers/components/AddressEditor.js +1 -1
  185. package/dist/modules/customers/components/AddressEditor.js.map +2 -2
  186. package/dist/modules/customers/components/CustomersConfigurationSections.js +31 -0
  187. package/dist/modules/customers/components/CustomersConfigurationSections.js.map +7 -0
  188. package/dist/modules/customers/components/DictionarySettings.js +37 -2
  189. package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
  190. package/dist/modules/customers/components/detail/ActiveDealCard.js +121 -0
  191. package/dist/modules/customers/components/detail/ActiveDealCard.js.map +7 -0
  192. package/dist/modules/customers/components/detail/ActivitiesSection.js +222 -331
  193. package/dist/modules/customers/components/detail/ActivitiesSection.js.map +3 -3
  194. package/dist/modules/customers/components/detail/ActivityAiActions.js +36 -0
  195. package/dist/modules/customers/components/detail/ActivityAiActions.js.map +7 -0
  196. package/dist/modules/customers/components/detail/ActivityCard.js +126 -0
  197. package/dist/modules/customers/components/detail/ActivityCard.js.map +7 -0
  198. package/dist/modules/customers/components/detail/ActivityHistorySection.js +340 -0
  199. package/dist/modules/customers/components/detail/ActivityHistorySection.js.map +7 -0
  200. package/dist/modules/customers/components/detail/ActivityLogTab.js +56 -0
  201. package/dist/modules/customers/components/detail/ActivityLogTab.js.map +7 -0
  202. package/dist/modules/customers/components/detail/ActivityTimeline.js +108 -0
  203. package/dist/modules/customers/components/detail/ActivityTimeline.js.map +7 -0
  204. package/dist/modules/customers/components/detail/ActivityTimelineFilters.js +139 -0
  205. package/dist/modules/customers/components/detail/ActivityTimelineFilters.js.map +7 -0
  206. package/dist/modules/customers/components/detail/ActivityTypeSelector.js +42 -0
  207. package/dist/modules/customers/components/detail/ActivityTypeSelector.js.map +7 -0
  208. package/dist/modules/customers/components/detail/AiActionChips.js +38 -0
  209. package/dist/modules/customers/components/detail/AiActionChips.js.map +7 -0
  210. package/dist/modules/customers/components/detail/AssignRoleDialog.js +534 -0
  211. package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +7 -0
  212. package/dist/modules/customers/components/detail/ChangelogEntryRow.js +79 -0
  213. package/dist/modules/customers/components/detail/ChangelogEntryRow.js.map +7 -0
  214. package/dist/modules/customers/components/detail/ChangelogFilters.js +176 -0
  215. package/dist/modules/customers/components/detail/ChangelogFilters.js.map +7 -0
  216. package/dist/modules/customers/components/detail/ChangelogKpiCards.js +88 -0
  217. package/dist/modules/customers/components/detail/ChangelogKpiCards.js.map +7 -0
  218. package/dist/modules/customers/components/detail/ChangelogTab.js +470 -0
  219. package/dist/modules/customers/components/detail/ChangelogTab.js.map +7 -0
  220. package/dist/modules/customers/components/detail/ComingSoonPlaceholder.js +16 -0
  221. package/dist/modules/customers/components/detail/ComingSoonPlaceholder.js.map +7 -0
  222. package/dist/modules/customers/components/detail/CompanyCard.js +283 -0
  223. package/dist/modules/customers/components/detail/CompanyCard.js.map +7 -0
  224. package/dist/modules/customers/components/detail/CompanyDashboardTab.js +133 -0
  225. package/dist/modules/customers/components/detail/CompanyDashboardTab.js.map +7 -0
  226. package/dist/modules/customers/components/detail/CompanyDetailHeader.js +191 -0
  227. package/dist/modules/customers/components/detail/CompanyDetailHeader.js.map +7 -0
  228. package/dist/modules/customers/components/detail/CompanyDetailTabs.js +123 -0
  229. package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +7 -0
  230. package/dist/modules/customers/components/detail/CompanyKpiBar.js +174 -0
  231. package/dist/modules/customers/components/detail/CompanyKpiBar.js.map +7 -0
  232. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +514 -230
  233. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  234. package/dist/modules/customers/components/detail/CompanyTagsDialog.js +22 -0
  235. package/dist/modules/customers/components/detail/CompanyTagsDialog.js.map +7 -0
  236. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js +159 -0
  237. package/dist/modules/customers/components/detail/ConfirmDealLostDialog.js.map +7 -0
  238. package/dist/modules/customers/components/detail/CreatePersonDialog.js +135 -0
  239. package/dist/modules/customers/components/detail/CreatePersonDialog.js.map +7 -0
  240. package/dist/modules/customers/components/detail/DealClosureActionBar.js +59 -0
  241. package/dist/modules/customers/components/detail/DealClosureActionBar.js.map +7 -0
  242. package/dist/modules/customers/components/detail/DealDetailHeader.js +237 -0
  243. package/dist/modules/customers/components/detail/DealDetailHeader.js.map +7 -0
  244. package/dist/modules/customers/components/detail/DealDetailTabs.js +109 -0
  245. package/dist/modules/customers/components/detail/DealDetailTabs.js.map +7 -0
  246. package/dist/modules/customers/components/detail/DealForm.js +219 -92
  247. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  248. package/dist/modules/customers/components/detail/DealLinkedEntitiesTab.js +295 -0
  249. package/dist/modules/customers/components/detail/DealLinkedEntitiesTab.js.map +7 -0
  250. package/dist/modules/customers/components/detail/DealLostSummaryDialog.js +107 -0
  251. package/dist/modules/customers/components/detail/DealLostSummaryDialog.js.map +7 -0
  252. package/dist/modules/customers/components/detail/DealWonPopup.js +113 -0
  253. package/dist/modules/customers/components/detail/DealWonPopup.js.map +7 -0
  254. package/dist/modules/customers/components/detail/DealsSection.js +206 -193
  255. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  256. package/dist/modules/customers/components/detail/DecisionMakersFooter.js +39 -0
  257. package/dist/modules/customers/components/detail/DecisionMakersFooter.js.map +7 -0
  258. package/dist/modules/customers/components/detail/EntityTagsDialog.js +1096 -0
  259. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +7 -0
  260. package/dist/modules/customers/components/detail/InlineActivityComposer.js +197 -0
  261. package/dist/modules/customers/components/detail/InlineActivityComposer.js.map +7 -0
  262. package/dist/modules/customers/components/detail/ManageTagsDialog.js +1091 -0
  263. package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +7 -0
  264. package/dist/modules/customers/components/detail/MiniWeekCalendar.js +272 -0
  265. package/dist/modules/customers/components/detail/MiniWeekCalendar.js.map +7 -0
  266. package/dist/modules/customers/components/detail/MobilePersonDetail.js +106 -0
  267. package/dist/modules/customers/components/detail/MobilePersonDetail.js.map +7 -0
  268. package/dist/modules/customers/components/detail/NextStepCard.js +72 -0
  269. package/dist/modules/customers/components/detail/NextStepCard.js.map +7 -0
  270. package/dist/modules/customers/components/detail/PersonCard.js +192 -0
  271. package/dist/modules/customers/components/detail/PersonCard.js.map +7 -0
  272. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +345 -0
  273. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +7 -0
  274. package/dist/modules/customers/components/detail/PersonDetailHeader.js +220 -0
  275. package/dist/modules/customers/components/detail/PersonDetailHeader.js.map +7 -0
  276. package/dist/modules/customers/components/detail/PersonDetailTabs.js +122 -0
  277. package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +7 -0
  278. package/dist/modules/customers/components/detail/PersonTagsDialog.js +24 -0
  279. package/dist/modules/customers/components/detail/PersonTagsDialog.js.map +7 -0
  280. package/dist/modules/customers/components/detail/PipelineStepper.js +191 -0
  281. package/dist/modules/customers/components/detail/PipelineStepper.js.map +7 -0
  282. package/dist/modules/customers/components/detail/PlannedActivitiesSection.js +222 -0
  283. package/dist/modules/customers/components/detail/PlannedActivitiesSection.js.map +7 -0
  284. package/dist/modules/customers/components/detail/RelationshipHealthCard.js +49 -0
  285. package/dist/modules/customers/components/detail/RelationshipHealthCard.js.map +7 -0
  286. package/dist/modules/customers/components/detail/RoleAssignmentRow.js +189 -0
  287. package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +7 -0
  288. package/dist/modules/customers/components/detail/RolesSection.js +234 -0
  289. package/dist/modules/customers/components/detail/RolesSection.js.map +7 -0
  290. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +410 -0
  291. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +7 -0
  292. package/dist/modules/customers/components/detail/aiActionCatalog.js +41 -0
  293. package/dist/modules/customers/components/detail/aiActionCatalog.js.map +7 -0
  294. package/dist/modules/customers/components/detail/assignableStaff.js +48 -0
  295. package/dist/modules/customers/components/detail/assignableStaff.js.map +7 -0
  296. package/dist/modules/customers/components/detail/dashboard/ActiveDealWidget.js +48 -0
  297. package/dist/modules/customers/components/detail/dashboard/ActiveDealWidget.js.map +7 -0
  298. package/dist/modules/customers/components/detail/dashboard/OpenTasksWidget.js +86 -0
  299. package/dist/modules/customers/components/detail/dashboard/OpenTasksWidget.js.map +7 -0
  300. package/dist/modules/customers/components/detail/dashboard/RecentActivityWidget.js +53 -0
  301. package/dist/modules/customers/components/detail/dashboard/RecentActivityWidget.js.map +7 -0
  302. package/dist/modules/customers/components/detail/dashboard/RelationshipHealthWidget.js +30 -0
  303. package/dist/modules/customers/components/detail/dashboard/RelationshipHealthWidget.js.map +7 -0
  304. package/dist/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.js +43 -0
  305. package/dist/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.js.map +7 -0
  306. package/dist/modules/customers/components/detail/dashboard/helpers.js +71 -0
  307. package/dist/modules/customers/components/detail/dashboard/helpers.js.map +7 -0
  308. package/dist/modules/customers/components/detail/healthScoreUtils.js +69 -0
  309. package/dist/modules/customers/components/detail/healthScoreUtils.js.map +7 -0
  310. package/dist/modules/customers/components/detail/hooks/useCurrencyDictionary.js +5 -5
  311. package/dist/modules/customers/components/detail/hooks/useCurrencyDictionary.js.map +2 -2
  312. package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js +9 -8
  313. package/dist/modules/customers/components/detail/hooks/useCustomerDictionary.js.map +3 -3
  314. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +65 -0
  315. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +7 -0
  316. package/dist/modules/customers/components/detail/notesAdapter.js +70 -30
  317. package/dist/modules/customers/components/detail/notesAdapter.js.map +2 -2
  318. package/dist/modules/customers/components/detail/pipelineStageUtils.js +26 -0
  319. package/dist/modules/customers/components/detail/pipelineStageUtils.js.map +7 -0
  320. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js +144 -0
  321. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js.map +7 -0
  322. package/dist/modules/customers/components/detail/schedule/FooterFields.js +60 -0
  323. package/dist/modules/customers/components/detail/schedule/FooterFields.js.map +7 -0
  324. package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js +216 -0
  325. package/dist/modules/customers/components/detail/schedule/LinkedEntitiesField.js.map +7 -0
  326. package/dist/modules/customers/components/detail/schedule/LocationField.js +34 -0
  327. package/dist/modules/customers/components/detail/schedule/LocationField.js.map +7 -0
  328. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +226 -0
  329. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +7 -0
  330. package/dist/modules/customers/components/detail/schedule/fieldConfig.js +69 -0
  331. package/dist/modules/customers/components/detail/schedule/fieldConfig.js.map +7 -0
  332. package/dist/modules/customers/components/detail/schedule/index.js +21 -0
  333. package/dist/modules/customers/components/detail/schedule/index.js.map +7 -0
  334. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +172 -0
  335. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +7 -0
  336. package/dist/modules/customers/components/detail/utils.js +23 -0
  337. package/dist/modules/customers/components/detail/utils.js.map +2 -2
  338. package/dist/modules/customers/components/formConfig.js +144 -22
  339. package/dist/modules/customers/components/formConfig.js.map +2 -2
  340. package/dist/modules/customers/components/linking/LinkEntityDialog.js +661 -0
  341. package/dist/modules/customers/components/linking/LinkEntityDialog.js.map +7 -0
  342. package/dist/modules/customers/components/linking/adapters/companyAdapter.js +252 -0
  343. package/dist/modules/customers/components/linking/adapters/companyAdapter.js.map +7 -0
  344. package/dist/modules/customers/components/linking/adapters/dealAdapter.js +384 -0
  345. package/dist/modules/customers/components/linking/adapters/dealAdapter.js.map +7 -0
  346. package/dist/modules/customers/components/linking/adapters/personAdapter.js +324 -0
  347. package/dist/modules/customers/components/linking/adapters/personAdapter.js.map +7 -0
  348. package/dist/modules/customers/components/list/CollectionPreviewCell.js +53 -0
  349. package/dist/modules/customers/components/list/CollectionPreviewCell.js.map +7 -0
  350. package/dist/modules/customers/data/entities.js +407 -1
  351. package/dist/modules/customers/data/entities.js.map +2 -2
  352. package/dist/modules/customers/data/validators.js +139 -21
  353. package/dist/modules/customers/data/validators.js.map +2 -2
  354. package/dist/modules/customers/events.js +19 -1
  355. package/dist/modules/customers/events.js.map +2 -2
  356. package/dist/modules/customers/lib/customerRoleTypes.js +19 -0
  357. package/dist/modules/customers/lib/customerRoleTypes.js.map +7 -0
  358. package/dist/modules/customers/lib/dealClosureNotification.js +39 -0
  359. package/dist/modules/customers/lib/dealClosureNotification.js.map +7 -0
  360. package/dist/modules/customers/lib/dealStageTransitionTable.js +29 -0
  361. package/dist/modules/customers/lib/dealStageTransitionTable.js.map +7 -0
  362. package/dist/modules/customers/lib/dictionaries.js +25 -0
  363. package/dist/modules/customers/lib/dictionaries.js.map +2 -2
  364. package/dist/modules/customers/lib/interactionReadModel.js +10 -0
  365. package/dist/modules/customers/lib/interactionReadModel.js.map +2 -2
  366. package/dist/modules/customers/lib/personCompanies.js +235 -0
  367. package/dist/modules/customers/lib/personCompanies.js.map +7 -0
  368. package/dist/modules/customers/lib/personCompanyLinkTable.js +42 -0
  369. package/dist/modules/customers/lib/personCompanyLinkTable.js.map +7 -0
  370. package/dist/modules/customers/lib/roleTypeUsage.js +104 -0
  371. package/dist/modules/customers/lib/roleTypeUsage.js.map +7 -0
  372. package/dist/modules/customers/migrations/Migration20260406214502.js +18 -0
  373. package/dist/modules/customers/migrations/Migration20260406214502.js.map +7 -0
  374. package/dist/modules/customers/migrations/Migration20260408135736.js +17 -0
  375. package/dist/modules/customers/migrations/Migration20260408135736.js.map +7 -0
  376. package/dist/modules/customers/migrations/Migration20260408225345.js +21 -0
  377. package/dist/modules/customers/migrations/Migration20260408225345.js.map +7 -0
  378. package/dist/modules/customers/migrations/Migration20260411075533.js +27 -0
  379. package/dist/modules/customers/migrations/Migration20260411075533.js.map +7 -0
  380. package/dist/modules/customers/migrations/Migration20260411103551.js +13 -0
  381. package/dist/modules/customers/migrations/Migration20260411103551.js.map +7 -0
  382. package/dist/modules/customers/migrations/Migration20260411130944.js +26 -0
  383. package/dist/modules/customers/migrations/Migration20260411130944.js.map +7 -0
  384. package/dist/modules/customers/migrations/Migration20260415095203.js +13 -0
  385. package/dist/modules/customers/migrations/Migration20260415095203.js.map +7 -0
  386. package/dist/modules/customers/migrations/Migration20260415135056.js +20 -0
  387. package/dist/modules/customers/migrations/Migration20260415135056.js.map +7 -0
  388. package/dist/modules/customers/migrations/Migration20260417140000.js +15 -0
  389. package/dist/modules/customers/migrations/Migration20260417140000.js.map +7 -0
  390. package/dist/modules/customers/migrations/Migration20260417160000.js +17 -0
  391. package/dist/modules/customers/migrations/Migration20260417160000.js.map +7 -0
  392. package/dist/modules/customers/migrations/Migration20260417235407.js +13 -0
  393. package/dist/modules/customers/migrations/Migration20260417235407.js.map +7 -0
  394. package/dist/modules/customers/setup.js +16 -1
  395. package/dist/modules/customers/setup.js.map +2 -2
  396. package/dist/modules/customers/subscribers/deal-closure-notification.js +16 -0
  397. package/dist/modules/customers/subscribers/deal-closure-notification.js.map +7 -0
  398. package/dist/modules/customers/subscribers/deal-lost-notification.js +16 -0
  399. package/dist/modules/customers/subscribers/deal-lost-notification.js.map +7 -0
  400. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +2 -0
  401. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  402. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js +154 -0
  403. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js.map +7 -0
  404. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +6 -2
  405. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
  406. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js +154 -0
  407. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js.map +7 -0
  408. package/dist/modules/dictionaries/api/context.js +8 -1
  409. package/dist/modules/dictionaries/api/context.js.map +2 -2
  410. package/dist/modules/dictionaries/api/openapi.js +18 -1
  411. package/dist/modules/dictionaries/api/openapi.js.map +2 -2
  412. package/dist/modules/dictionaries/commands/entry-operations.js +388 -0
  413. package/dist/modules/dictionaries/commands/entry-operations.js.map +7 -0
  414. package/dist/modules/dictionaries/commands/factory.js +24 -3
  415. package/dist/modules/dictionaries/commands/factory.js.map +2 -2
  416. package/dist/modules/dictionaries/commands/index.js +1 -0
  417. package/dist/modules/dictionaries/commands/index.js.map +2 -2
  418. package/dist/modules/dictionaries/components/DictionaryTable.js +6 -3
  419. package/dist/modules/dictionaries/components/DictionaryTable.js.map +2 -2
  420. package/dist/modules/dictionaries/data/entities.js +11 -1
  421. package/dist/modules/dictionaries/data/entities.js.map +2 -2
  422. package/dist/modules/dictionaries/data/validators.js +28 -2
  423. package/dist/modules/dictionaries/data/validators.js.map +2 -2
  424. package/dist/modules/dictionaries/events.js +18 -0
  425. package/dist/modules/dictionaries/events.js.map +7 -0
  426. package/dist/modules/dictionaries/lib/clientEntries.js +43 -0
  427. package/dist/modules/dictionaries/lib/clientEntries.js.map +7 -0
  428. package/dist/modules/dictionaries/migrations/Migration20260410171544.js +45 -0
  429. package/dist/modules/dictionaries/migrations/Migration20260410171544.js.map +7 -0
  430. package/dist/modules/inbox_ops/api/proposals/[id]/route.js +4 -1
  431. package/dist/modules/inbox_ops/api/proposals/[id]/route.js.map +2 -2
  432. package/dist/modules/query_index/lib/engine.js +1 -1
  433. package/dist/modules/query_index/lib/engine.js.map +2 -2
  434. package/dist/modules/sales/components/documents/AddressesSection.js +82 -42
  435. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  436. package/dist/modules/sales/lib/dictionaries.js +16 -0
  437. package/dist/modules/sales/lib/dictionaries.js.map +2 -2
  438. package/dist/modules/sales/widgets/injection-table.js +5 -1
  439. package/dist/modules/sales/widgets/injection-table.js.map +2 -2
  440. package/generated/entities/action_log/index.ts +4 -0
  441. package/generated/entities/customer_company_billing/index.ts +10 -0
  442. package/generated/entities/customer_deal/index.ts +4 -0
  443. package/generated/entities/customer_deal_stage_transition/index.ts +14 -0
  444. package/generated/entities/customer_dictionary_kind_setting/index.ts +9 -0
  445. package/generated/entities/customer_entity/index.ts +4 -0
  446. package/generated/entities/customer_entity_role/index.ts +10 -0
  447. package/generated/entities/customer_interaction/index.ts +11 -0
  448. package/generated/entities/customer_label/index.ts +8 -0
  449. package/generated/entities/customer_label_assignment/index.ts +7 -0
  450. package/generated/entities/customer_person_company_link/index.ts +9 -0
  451. package/generated/entities/customer_person_company_role/index.ts +7 -0
  452. package/generated/entities/dictionary_entry/index.ts +2 -0
  453. package/generated/entities.ids.generated.ts +9 -1
  454. package/generated/entity-fields-registry.ts +116 -1
  455. package/package.json +3 -3
  456. package/src/modules/attachments/api/route.ts +48 -6
  457. package/src/modules/attachments/i18n/de.json +4 -0
  458. package/src/modules/attachments/i18n/en.json +4 -0
  459. package/src/modules/attachments/i18n/es.json +4 -0
  460. package/src/modules/attachments/i18n/pl.json +4 -0
  461. package/src/modules/audit_logs/api/audit-logs/actions/export/route.ts +260 -0
  462. package/src/modules/audit_logs/api/audit-logs/actions/route.ts +81 -6
  463. package/src/modules/audit_logs/cli.ts +79 -0
  464. package/src/modules/audit_logs/data/entities.ts +17 -0
  465. package/src/modules/audit_logs/data/validators.ts +9 -1
  466. package/src/modules/audit_logs/lib/changeRows.ts +47 -0
  467. package/src/modules/audit_logs/lib/display-helpers.tsx +4 -30
  468. package/src/modules/audit_logs/lib/projections.ts +110 -0
  469. package/src/modules/audit_logs/migrations/.snapshot-open-mercato.json +325 -2
  470. package/src/modules/audit_logs/migrations/Migration20260412160533.ts +21 -0
  471. package/src/modules/audit_logs/services/actionLogService.ts +455 -85
  472. package/src/modules/catalog/i18n/de.json +1 -0
  473. package/src/modules/catalog/i18n/en.json +1 -0
  474. package/src/modules/catalog/i18n/es.json +1 -0
  475. package/src/modules/catalog/i18n/pl.json +1 -0
  476. package/src/modules/customer_accounts/i18n/de.json +2 -0
  477. package/src/modules/customer_accounts/i18n/en.json +2 -0
  478. package/src/modules/customer_accounts/i18n/es.json +2 -0
  479. package/src/modules/customer_accounts/i18n/pl.json +2 -0
  480. package/src/modules/customers/acl.ts +2 -0
  481. package/src/modules/customers/api/activities/route.ts +4 -0
  482. package/src/modules/customers/api/assignable-staff/route.ts +250 -0
  483. package/src/modules/customers/api/companies/[id]/people/route.ts +244 -0
  484. package/src/modules/customers/api/companies/[id]/roles/route.ts +15 -0
  485. package/src/modules/customers/api/companies/[id]/route.ts +458 -40
  486. package/src/modules/customers/api/companies/route.ts +93 -15
  487. package/src/modules/customers/api/deals/[id]/companies/route.ts +203 -0
  488. package/src/modules/customers/api/deals/[id]/people/route.ts +182 -0
  489. package/src/modules/customers/api/deals/[id]/route.ts +554 -57
  490. package/src/modules/customers/api/deals/[id]/stats/route.ts +221 -0
  491. package/src/modules/customers/api/deals/route.ts +35 -46
  492. package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +105 -3
  493. package/src/modules/customers/api/dictionaries/[kind]/route.ts +143 -44
  494. package/src/modules/customers/api/dictionaries/context.ts +45 -16
  495. package/src/modules/customers/api/dictionaries/kind-settings/route.ts +232 -0
  496. package/src/modules/customers/api/entity-roles-factory.ts +520 -0
  497. package/src/modules/customers/api/interactions/conflicts/route.ts +196 -0
  498. package/src/modules/customers/api/interactions/counts/route.ts +112 -0
  499. package/src/modules/customers/api/interactions/route.ts +95 -2
  500. package/src/modules/customers/api/labels/assign/route.ts +202 -0
  501. package/src/modules/customers/api/labels/auth.ts +19 -0
  502. package/src/modules/customers/api/labels/route.ts +310 -0
  503. package/src/modules/customers/api/labels/table-errors.ts +36 -0
  504. package/src/modules/customers/api/labels/unassign/route.ts +197 -0
  505. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +331 -0
  506. package/src/modules/customers/api/people/[id]/companies/context.ts +70 -0
  507. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +384 -0
  508. package/src/modules/customers/api/people/[id]/companies/route.ts +215 -0
  509. package/src/modules/customers/api/people/[id]/roles/route.ts +15 -0
  510. package/src/modules/customers/api/people/[id]/route.ts +153 -26
  511. package/src/modules/customers/api/people/route.ts +134 -31
  512. package/src/modules/customers/api/todos/route.ts +4 -0
  513. package/src/modules/customers/api/utils.ts +36 -0
  514. package/src/modules/customers/backend/config/customers/page.tsx +2 -6
  515. package/src/modules/customers/backend/customers/companies/page.tsx +36 -26
  516. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +277 -262
  517. package/src/modules/customers/backend/customers/deals/[id]/hooks/formatters.ts +19 -0
  518. package/src/modules/customers/backend/customers/deals/[id]/hooks/types.ts +104 -0
  519. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealActivities.ts +60 -0
  520. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealAssociations.ts +362 -0
  521. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealClosure.ts +113 -0
  522. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealData.ts +52 -0
  523. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +86 -0
  524. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealInjectedTabs.tsx +60 -0
  525. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealMutationContext.ts +76 -0
  526. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealPipeline.ts +56 -0
  527. package/src/modules/customers/backend/customers/deals/[id]/hooks/useScheduleDialog.ts +38 -0
  528. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +587 -624
  529. package/src/modules/customers/backend/customers/deals/page.tsx +71 -28
  530. package/src/modules/customers/backend/customers/people/page.tsx +35 -29
  531. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +343 -209
  532. package/src/modules/customers/cli.ts +107 -12
  533. package/src/modules/customers/commands/activities.ts +13 -0
  534. package/src/modules/customers/commands/deals.ts +386 -114
  535. package/src/modules/customers/commands/dictionaries.ts +175 -32
  536. package/src/modules/customers/commands/dictionaryKindSettings.ts +268 -0
  537. package/src/modules/customers/commands/entity-roles.ts +494 -0
  538. package/src/modules/customers/commands/index.ts +4 -0
  539. package/src/modules/customers/commands/interactions.ts +125 -21
  540. package/src/modules/customers/commands/labels.ts +626 -0
  541. package/src/modules/customers/commands/people.ts +373 -259
  542. package/src/modules/customers/commands/personCompanyLinks.ts +654 -0
  543. package/src/modules/customers/commands/shared.ts +16 -15
  544. package/src/modules/customers/commands/todos.ts +17 -1
  545. package/src/modules/customers/components/AddressEditor.tsx +1 -1
  546. package/src/modules/customers/components/CustomersConfigurationSections.tsx +36 -0
  547. package/src/modules/customers/components/DictionarySettings.tsx +43 -2
  548. package/src/modules/customers/components/detail/ActiveDealCard.tsx +175 -0
  549. package/src/modules/customers/components/detail/ActivitiesSection.tsx +267 -361
  550. package/src/modules/customers/components/detail/ActivityAiActions.tsx +49 -0
  551. package/src/modules/customers/components/detail/ActivityCard.tsx +154 -0
  552. package/src/modules/customers/components/detail/ActivityHistorySection.tsx +412 -0
  553. package/src/modules/customers/components/detail/ActivityLogTab.tsx +67 -0
  554. package/src/modules/customers/components/detail/ActivityTimeline.tsx +158 -0
  555. package/src/modules/customers/components/detail/ActivityTimelineFilters.tsx +163 -0
  556. package/src/modules/customers/components/detail/ActivityTypeSelector.tsx +53 -0
  557. package/src/modules/customers/components/detail/AiActionChips.tsx +48 -0
  558. package/src/modules/customers/components/detail/AssignRoleDialog.tsx +672 -0
  559. package/src/modules/customers/components/detail/ChangelogEntryRow.tsx +132 -0
  560. package/src/modules/customers/components/detail/ChangelogFilters.tsx +193 -0
  561. package/src/modules/customers/components/detail/ChangelogKpiCards.tsx +107 -0
  562. package/src/modules/customers/components/detail/ChangelogTab.tsx +629 -0
  563. package/src/modules/customers/components/detail/ComingSoonPlaceholder.tsx +21 -0
  564. package/src/modules/customers/components/detail/CompanyCard.tsx +419 -0
  565. package/src/modules/customers/components/detail/CompanyDashboardTab.tsx +161 -0
  566. package/src/modules/customers/components/detail/CompanyDetailHeader.tsx +243 -0
  567. package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +172 -0
  568. package/src/modules/customers/components/detail/CompanyKpiBar.tsx +206 -0
  569. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +582 -288
  570. package/src/modules/customers/components/detail/CompanyTagsDialog.tsx +23 -0
  571. package/src/modules/customers/components/detail/ConfirmDealLostDialog.tsx +210 -0
  572. package/src/modules/customers/components/detail/CreatePersonDialog.tsx +178 -0
  573. package/src/modules/customers/components/detail/DealClosureActionBar.tsx +63 -0
  574. package/src/modules/customers/components/detail/DealDetailHeader.tsx +335 -0
  575. package/src/modules/customers/components/detail/DealDetailTabs.tsx +154 -0
  576. package/src/modules/customers/components/detail/DealForm.tsx +253 -101
  577. package/src/modules/customers/components/detail/DealLinkedEntitiesTab.tsx +349 -0
  578. package/src/modules/customers/components/detail/DealLostSummaryDialog.tsx +156 -0
  579. package/src/modules/customers/components/detail/DealWonPopup.tsx +164 -0
  580. package/src/modules/customers/components/detail/DealsSection.tsx +276 -221
  581. package/src/modules/customers/components/detail/DecisionMakersFooter.tsx +56 -0
  582. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +1372 -0
  583. package/src/modules/customers/components/detail/InlineActivityComposer.tsx +239 -0
  584. package/src/modules/customers/components/detail/ManageTagsDialog.tsx +1331 -0
  585. package/src/modules/customers/components/detail/MiniWeekCalendar.tsx +338 -0
  586. package/src/modules/customers/components/detail/MobilePersonDetail.tsx +124 -0
  587. package/src/modules/customers/components/detail/NextStepCard.tsx +104 -0
  588. package/src/modules/customers/components/detail/PersonCard.tsx +238 -0
  589. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +426 -0
  590. package/src/modules/customers/components/detail/PersonDetailHeader.tsx +294 -0
  591. package/src/modules/customers/components/detail/PersonDetailTabs.tsx +172 -0
  592. package/src/modules/customers/components/detail/PersonTagsDialog.tsx +26 -0
  593. package/src/modules/customers/components/detail/PipelineStepper.tsx +245 -0
  594. package/src/modules/customers/components/detail/PlannedActivitiesSection.tsx +255 -0
  595. package/src/modules/customers/components/detail/RelationshipHealthCard.tsx +63 -0
  596. package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +248 -0
  597. package/src/modules/customers/components/detail/RolesSection.tsx +311 -0
  598. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +481 -0
  599. package/src/modules/customers/components/detail/aiActionCatalog.ts +77 -0
  600. package/src/modules/customers/components/detail/assignableStaff.ts +124 -0
  601. package/src/modules/customers/components/detail/dashboard/ActiveDealWidget.tsx +63 -0
  602. package/src/modules/customers/components/detail/dashboard/OpenTasksWidget.tsx +114 -0
  603. package/src/modules/customers/components/detail/dashboard/RecentActivityWidget.tsx +69 -0
  604. package/src/modules/customers/components/detail/dashboard/RelationshipHealthWidget.tsx +40 -0
  605. package/src/modules/customers/components/detail/dashboard/UpcomingMeetingsWidget.tsx +64 -0
  606. package/src/modules/customers/components/detail/dashboard/helpers.ts +78 -0
  607. package/src/modules/customers/components/detail/healthScoreUtils.ts +91 -0
  608. package/src/modules/customers/components/detail/hooks/useCurrencyDictionary.ts +8 -8
  609. package/src/modules/customers/components/detail/hooks/useCustomerDictionary.ts +10 -6
  610. package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +91 -0
  611. package/src/modules/customers/components/detail/notesAdapter.ts +91 -30
  612. package/src/modules/customers/components/detail/pipelineStageUtils.ts +29 -0
  613. package/src/modules/customers/components/detail/schedule/DateTimeFields.tsx +187 -0
  614. package/src/modules/customers/components/detail/schedule/FooterFields.tsx +79 -0
  615. package/src/modules/customers/components/detail/schedule/LinkedEntitiesField.tsx +277 -0
  616. package/src/modules/customers/components/detail/schedule/LocationField.tsx +42 -0
  617. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +255 -0
  618. package/src/modules/customers/components/detail/schedule/fieldConfig.ts +70 -0
  619. package/src/modules/customers/components/detail/schedule/index.ts +9 -0
  620. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +221 -0
  621. package/src/modules/customers/components/detail/types.ts +16 -0
  622. package/src/modules/customers/components/detail/utils.ts +25 -0
  623. package/src/modules/customers/components/formConfig.tsx +223 -28
  624. package/src/modules/customers/components/linking/LinkEntityDialog.tsx +920 -0
  625. package/src/modules/customers/components/linking/adapters/companyAdapter.tsx +398 -0
  626. package/src/modules/customers/components/linking/adapters/dealAdapter.tsx +578 -0
  627. package/src/modules/customers/components/linking/adapters/personAdapter.tsx +512 -0
  628. package/src/modules/customers/components/list/CollectionPreviewCell.tsx +66 -0
  629. package/src/modules/customers/data/entities.ts +353 -1
  630. package/src/modules/customers/data/validators.ts +170 -19
  631. package/src/modules/customers/events.ts +22 -0
  632. package/src/modules/customers/i18n/de.json +841 -2
  633. package/src/modules/customers/i18n/en.json +841 -2
  634. package/src/modules/customers/i18n/es.json +840 -1
  635. package/src/modules/customers/i18n/pl.json +841 -2
  636. package/src/modules/customers/lib/customerRoleTypes.ts +24 -0
  637. package/src/modules/customers/lib/dealClosureNotification.ts +64 -0
  638. package/src/modules/customers/lib/dealStageTransitionTable.ts +32 -0
  639. package/src/modules/customers/lib/dictionaries.ts +26 -10
  640. package/src/modules/customers/lib/interactionReadModel.ts +10 -0
  641. package/src/modules/customers/lib/personCompanies.ts +317 -0
  642. package/src/modules/customers/lib/personCompanyLinkTable.ts +58 -0
  643. package/src/modules/customers/lib/roleTypeUsage.ts +146 -0
  644. package/src/modules/customers/migrations/.snapshot-open-mercato.json +2747 -798
  645. package/src/modules/customers/migrations/Migration20260406214502.ts +19 -0
  646. package/src/modules/customers/migrations/Migration20260408135736.ts +15 -0
  647. package/src/modules/customers/migrations/Migration20260408225345.ts +23 -0
  648. package/src/modules/customers/migrations/Migration20260411075533.ts +30 -0
  649. package/src/modules/customers/migrations/Migration20260411103551.ts +13 -0
  650. package/src/modules/customers/migrations/Migration20260411130944.ts +30 -0
  651. package/src/modules/customers/migrations/Migration20260415095203.ts +13 -0
  652. package/src/modules/customers/migrations/Migration20260415135056.ts +22 -0
  653. package/src/modules/customers/migrations/Migration20260417140000.ts +15 -0
  654. package/src/modules/customers/migrations/Migration20260417160000.ts +17 -0
  655. package/src/modules/customers/migrations/Migration20260417235407.ts +13 -0
  656. package/src/modules/customers/setup.ts +15 -0
  657. package/src/modules/customers/subscribers/deal-closure-notification.ts +22 -0
  658. package/src/modules/customers/subscribers/deal-lost-notification.ts +22 -0
  659. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +2 -0
  660. package/src/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.ts +162 -0
  661. package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +6 -2
  662. package/src/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.ts +162 -0
  663. package/src/modules/dictionaries/api/context.ts +9 -0
  664. package/src/modules/dictionaries/api/openapi.ts +17 -0
  665. package/src/modules/dictionaries/commands/entry-operations.ts +457 -0
  666. package/src/modules/dictionaries/commands/factory.ts +31 -3
  667. package/src/modules/dictionaries/commands/index.ts +1 -0
  668. package/src/modules/dictionaries/components/DictionaryTable.tsx +15 -6
  669. package/src/modules/dictionaries/data/entities.ts +9 -0
  670. package/src/modules/dictionaries/data/validators.ts +34 -0
  671. package/src/modules/dictionaries/events.ts +20 -0
  672. package/src/modules/dictionaries/i18n/de.json +2 -0
  673. package/src/modules/dictionaries/i18n/en.json +2 -0
  674. package/src/modules/dictionaries/i18n/es.json +2 -0
  675. package/src/modules/dictionaries/i18n/pl.json +2 -0
  676. package/src/modules/dictionaries/lib/clientEntries.ts +66 -0
  677. package/src/modules/dictionaries/migrations/.snapshot-open-mercato.json +185 -3
  678. package/src/modules/dictionaries/migrations/Migration20260410171544.ts +49 -0
  679. package/src/modules/inbox_ops/api/proposals/[id]/route.ts +4 -1
  680. package/src/modules/query_index/lib/engine.ts +9 -1
  681. package/src/modules/sales/components/documents/AddressesSection.tsx +92 -42
  682. package/src/modules/sales/i18n/de.json +28 -0
  683. package/src/modules/sales/i18n/en.json +28 -0
  684. package/src/modules/sales/i18n/es.json +28 -0
  685. package/src/modules/sales/i18n/pl.json +28 -0
  686. package/src/modules/sales/lib/dictionaries.ts +18 -0
  687. package/src/modules/sales/widgets/injection-table.ts +4 -0
@@ -0,0 +1,191 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { Phone, Mail, Trash2, Building2, Globe, Pencil, MapPin } from "lucide-react";
5
+ import { useQueryClient } from "@tanstack/react-query";
6
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
7
+ import { Button } from "@open-mercato/ui/primitives/button";
8
+ import { IconButton } from "@open-mercato/ui/primitives/icon-button";
9
+ import { Badge } from "@open-mercato/ui/primitives/badge";
10
+ import { CompanyTagsDialog } from "./CompanyTagsDialog.js";
11
+ import { invalidateCustomerDictionary, useCustomerDictionary } from "./hooks/useCustomerDictionary.js";
12
+ import { renderDictionaryIcon } from "../../../dictionaries/components/dictionaryAppearance.js";
13
+ import { formatFallbackLabel } from "./utils.js";
14
+ function CompanyDictionaryBadge({ value, map }) {
15
+ const entry = map?.[value];
16
+ const color = entry?.color ?? null;
17
+ const icon = entry?.icon ?? null;
18
+ const label = entry?.label ?? formatFallbackLabel(value);
19
+ const colorStyle = color ? { color, borderColor: color, backgroundColor: `${color}1A` } : void 0;
20
+ return /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "rounded-sm gap-1.5 text-xs font-medium", style: colorStyle, children: [
21
+ icon ? renderDictionaryIcon(icon, "size-2.5") : null,
22
+ label
23
+ ] });
24
+ }
25
+ function CompanyDetailHeader({
26
+ data,
27
+ onTagsChange,
28
+ tagsSectionControllerRef,
29
+ onSave,
30
+ onDelete,
31
+ isDirty,
32
+ isSaving,
33
+ onFocusField,
34
+ onDataReload
35
+ }) {
36
+ const t = useT();
37
+ const queryClient = useQueryClient();
38
+ const [manageTagsOpen, setManageTagsOpen] = React.useState(false);
39
+ const company = data.company;
40
+ const profile = data.profile;
41
+ const displayName = company.displayName || t("customers.companies.detail.untitled", "Untitled");
42
+ const visibleCustomTags = React.useMemo(
43
+ () => data.tags?.filter((tag) => !["status", "lifecycle_stage", "source"].includes(tag.id)).slice(0, 6) ?? [],
44
+ [data.tags]
45
+ );
46
+ const hiddenCustomTagsCount = Math.max(
47
+ 0,
48
+ (data.tags?.filter((tag) => !["status", "lifecycle_stage", "source"].includes(tag.id)).length ?? 0) - visibleCustomTags.length
49
+ );
50
+ const industryLabel = profile?.industry ?? null;
51
+ const sizeLabel = profile?.sizeBucket ?? null;
52
+ const subtitle = [industryLabel, sizeLabel ? t("customers.companies.detail.header.employees", "{count} employees", { count: sizeLabel }) : null].filter(Boolean).join(" \xB7 ");
53
+ const primaryAddress = React.useMemo(() => {
54
+ const addresses = data.addresses;
55
+ if (!addresses || !Array.isArray(addresses)) return null;
56
+ return addresses.find((a) => a.isPrimary) ?? addresses[0] ?? null;
57
+ }, [data]);
58
+ const locationText = React.useMemo(() => {
59
+ if (!primaryAddress) return null;
60
+ return [primaryAddress.city, primaryAddress.region, primaryAddress.postalCode].filter(Boolean).join(", ");
61
+ }, [primaryAddress]);
62
+ const companyOrgId = company.organizationId ?? null;
63
+ const { data: statusDict } = useCustomerDictionary("statuses", 0, companyOrgId);
64
+ const { data: lifecycleDict } = useCustomerDictionary("lifecycle-stages", 0, companyOrgId);
65
+ const { data: sourceDict } = useCustomerDictionary("sources", 0, companyOrgId);
66
+ const { data: temperatureDict } = useCustomerDictionary("temperature", 0, companyOrgId);
67
+ const { data: renewalQuarterDict } = useCustomerDictionary("renewal-quarters", 0, companyOrgId);
68
+ return /* @__PURE__ */ jsxs("div", { className: "rounded-lg border bg-card", children: [
69
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-4 px-6 pt-6 pb-3 sm:flex-row sm:items-start sm:gap-5", children: [
70
+ /* @__PURE__ */ jsx("div", { className: "flex size-18 shrink-0 items-center justify-center rounded-full bg-muted", children: /* @__PURE__ */ jsx(Building2, { className: "size-7 text-muted-foreground" }) }),
71
+ /* @__PURE__ */ jsxs("div", { className: "min-w-0 flex-1", children: [
72
+ /* @__PURE__ */ jsx("h1", { className: "truncate text-2xl font-bold text-foreground", children: displayName }),
73
+ subtitle && /* @__PURE__ */ jsx("p", { className: "mt-0.5 text-sm text-muted-foreground", children: subtitle }),
74
+ /* @__PURE__ */ jsxs("div", { className: "mt-1.5 flex flex-wrap items-center gap-x-5 gap-y-1 text-sm text-muted-foreground", children: [
75
+ company.primaryPhone && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
76
+ /* @__PURE__ */ jsx(Phone, { className: "size-3.5" }),
77
+ /* @__PURE__ */ jsx("a", { href: `tel:${company.primaryPhone}`, className: "hover:text-foreground", children: company.primaryPhone })
78
+ ] }),
79
+ company.primaryEmail && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
80
+ /* @__PURE__ */ jsx(Mail, { className: "size-3.5" }),
81
+ /* @__PURE__ */ jsx("a", { href: `mailto:${company.primaryEmail}`, className: "hover:text-foreground", children: company.primaryEmail })
82
+ ] }),
83
+ profile?.websiteUrl && /* @__PURE__ */ jsxs("a", { href: profile.websiteUrl.startsWith("http") ? profile.websiteUrl : `https://${profile.websiteUrl}`, target: "_blank", rel: "noreferrer", className: "inline-flex items-center gap-1.5 hover:text-foreground", children: [
84
+ /* @__PURE__ */ jsx(Globe, { className: "size-3.5" }),
85
+ profile.websiteUrl
86
+ ] }),
87
+ locationText && /* @__PURE__ */ jsxs("span", { className: "inline-flex items-center gap-1.5", children: [
88
+ /* @__PURE__ */ jsx(MapPin, { className: "size-3.5" }),
89
+ locationText
90
+ ] })
91
+ ] }),
92
+ /* @__PURE__ */ jsxs("div", { className: "mt-2.5 flex flex-wrap items-center gap-1.5", children: [
93
+ company.status && /* @__PURE__ */ jsx(CompanyDictionaryBadge, { value: company.status, map: statusDict?.map }),
94
+ company.lifecycleStage && /* @__PURE__ */ jsx(CompanyDictionaryBadge, { value: company.lifecycleStage, map: lifecycleDict?.map }),
95
+ company.source && /* @__PURE__ */ jsx(CompanyDictionaryBadge, { value: company.source, map: sourceDict?.map }),
96
+ company.temperature && /* @__PURE__ */ jsx(CompanyDictionaryBadge, { value: company.temperature, map: temperatureDict?.map }),
97
+ company.renewalQuarter && /* @__PURE__ */ jsx(CompanyDictionaryBadge, { value: company.renewalQuarter, map: renewalQuarterDict?.map }),
98
+ visibleCustomTags.map((tag) => {
99
+ const colorStyle = tag.color ? { color: tag.color, borderColor: tag.color, backgroundColor: `${tag.color}1A` } : void 0;
100
+ return /* @__PURE__ */ jsx(
101
+ Badge,
102
+ {
103
+ variant: "outline",
104
+ className: "rounded-sm gap-1.5 text-xs font-medium",
105
+ style: colorStyle,
106
+ children: tag.label
107
+ },
108
+ tag.id
109
+ );
110
+ }),
111
+ hiddenCustomTagsCount > 0 ? /* @__PURE__ */ jsxs(Badge, { variant: "outline", className: "rounded-sm gap-1.5 text-xs font-medium", children: [
112
+ "+",
113
+ hiddenCustomTagsCount,
114
+ " ",
115
+ t("customers.companies.detail.header.more", "more")
116
+ ] }) : null,
117
+ /* @__PURE__ */ jsxs(
118
+ Button,
119
+ {
120
+ type: "button",
121
+ variant: "outline",
122
+ size: "sm",
123
+ className: "h-auto rounded-sm px-2 py-1 text-xs font-medium text-muted-foreground hover:text-foreground",
124
+ onClick: () => setManageTagsOpen(true),
125
+ children: [
126
+ /* @__PURE__ */ jsx(Pencil, { className: "mr-1 size-3" }),
127
+ t("customers.companies.detail.actions.manageTags", "Edit tags")
128
+ ]
129
+ }
130
+ )
131
+ ] })
132
+ ] }),
133
+ /* @__PURE__ */ jsx("div", { className: "flex w-full shrink-0 flex-col items-start gap-3 sm:w-auto sm:items-end", children: /* @__PURE__ */ jsxs("div", { className: "flex w-full flex-wrap items-center justify-start gap-2 sm:w-auto sm:justify-end", children: [
134
+ /* @__PURE__ */ jsx(
135
+ IconButton,
136
+ {
137
+ variant: "outline",
138
+ size: "sm",
139
+ type: "button",
140
+ "aria-label": t("customers.companies.detail.actions.delete", "Delete company"),
141
+ onClick: () => {
142
+ void onDelete();
143
+ },
144
+ children: /* @__PURE__ */ jsx(Trash2, { className: "size-4" })
145
+ }
146
+ ),
147
+ /* @__PURE__ */ jsx(
148
+ Button,
149
+ {
150
+ type: "button",
151
+ size: "sm",
152
+ onClick: onSave,
153
+ disabled: !isDirty || isSaving,
154
+ children: t("customers.companies.detail.actions.save", "Save")
155
+ }
156
+ )
157
+ ] }) })
158
+ ] }),
159
+ /* @__PURE__ */ jsx(
160
+ CompanyTagsDialog,
161
+ {
162
+ open: manageTagsOpen,
163
+ onClose: () => setManageTagsOpen(false),
164
+ entityId: company.id,
165
+ companyOrganizationId: company.organizationId ?? null,
166
+ companyData: {
167
+ status: company.status,
168
+ lifecycleStage: company.lifecycleStage,
169
+ source: company.source,
170
+ temperature: company.temperature,
171
+ renewalQuarter: company.renewalQuarter,
172
+ industry: profile?.industry ?? null,
173
+ customFields: data.customFields,
174
+ tags: data.tags
175
+ },
176
+ onSaved: () => {
177
+ void invalidateCustomerDictionary(queryClient, "statuses");
178
+ void invalidateCustomerDictionary(queryClient, "lifecycle-stages");
179
+ void invalidateCustomerDictionary(queryClient, "sources");
180
+ void invalidateCustomerDictionary(queryClient, "temperature");
181
+ void invalidateCustomerDictionary(queryClient, "renewal-quarters");
182
+ onDataReload?.();
183
+ }
184
+ }
185
+ )
186
+ ] });
187
+ }
188
+ export {
189
+ CompanyDetailHeader
190
+ };
191
+ //# sourceMappingURL=CompanyDetailHeader.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/customers/components/detail/CompanyDetailHeader.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Phone, Mail, Trash2, Building2, Globe, Pencil, MapPin } from 'lucide-react'\nimport { useQueryClient } from '@tanstack/react-query'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport { CompanyTagsDialog } from './CompanyTagsDialog'\nimport { invalidateCustomerDictionary, useCustomerDictionary } from './hooks/useCustomerDictionary'\nimport { renderDictionaryIcon } from '../../../dictionaries/components/dictionaryAppearance'\nimport type { TagSummary } from './types'\nimport type { TagsSectionController } from '@open-mercato/ui/backend/detail'\nimport type { CompanyOverview } from '../formConfig'\nimport type { CustomerDictionaryMap } from '@open-mercato/core/modules/customers/lib/dictionaries'\nimport { formatFallbackLabel } from './utils'\n\ntype CompanyDetailHeaderProps = {\n data: CompanyOverview\n onTagsChange: (tags: TagSummary[]) => void\n tagsSectionControllerRef: React.RefObject<TagsSectionController | null>\n onSave: () => void\n onDelete: () => Promise<void>\n isDirty: boolean\n isSaving: boolean\n onFocusField?: (fieldName: string) => void\n onDataReload?: () => void\n}\n\nfunction CompanyDictionaryBadge({ value, map }: { value: string; map: CustomerDictionaryMap | undefined }) {\n const entry = map?.[value]\n const color = entry?.color ?? null\n const icon = entry?.icon ?? null\n const label = entry?.label ?? formatFallbackLabel(value)\n const colorStyle: React.CSSProperties | undefined = color\n ? { color, borderColor: color, backgroundColor: `${color}1A` }\n : undefined\n return (\n <Badge variant=\"outline\" className=\"rounded-sm gap-1.5 text-xs font-medium\" style={colorStyle}>\n {icon ? renderDictionaryIcon(icon, 'size-2.5') : null}\n {label}\n </Badge>\n )\n}\n\nexport function CompanyDetailHeader({\n data,\n onTagsChange,\n tagsSectionControllerRef,\n onSave,\n onDelete,\n isDirty,\n isSaving,\n onFocusField,\n onDataReload,\n}: CompanyDetailHeaderProps) {\n const t = useT()\n const queryClient = useQueryClient()\n const [manageTagsOpen, setManageTagsOpen] = React.useState(false)\n const company = data.company\n const profile = data.profile\n const displayName = company.displayName || t('customers.companies.detail.untitled', 'Untitled')\n const visibleCustomTags = React.useMemo(\n () => (data.tags?.filter((tag) => !['status', 'lifecycle_stage', 'source'].includes(tag.id)).slice(0, 6) ?? []),\n [data.tags],\n )\n const hiddenCustomTagsCount = Math.max(\n 0,\n (data.tags?.filter((tag) => !['status', 'lifecycle_stage', 'source'].includes(tag.id)).length ?? 0) - visibleCustomTags.length,\n )\n\n const industryLabel = profile?.industry ?? null\n const sizeLabel = profile?.sizeBucket ?? null\n const subtitle = [industryLabel, sizeLabel ? t('customers.companies.detail.header.employees', '{count} employees', { count: sizeLabel }) : null].filter(Boolean).join(' \\u00b7 ')\n\n // Primary address for header\n const primaryAddress = React.useMemo(() => {\n const addresses = (data as Record<string, unknown>).addresses as Array<{ isPrimary?: boolean; city?: string; region?: string; postalCode?: string }> | undefined\n if (!addresses || !Array.isArray(addresses)) return null\n return addresses.find((a) => a.isPrimary) ?? addresses[0] ?? null\n }, [data])\n\n const locationText = React.useMemo(() => {\n if (!primaryAddress) return null\n return [primaryAddress.city, primaryAddress.region, primaryAddress.postalCode].filter(Boolean).join(', ')\n }, [primaryAddress])\n\n // Fetch dictionary maps for colored badge rendering\n const companyOrgId = company.organizationId ?? null\n const { data: statusDict } = useCustomerDictionary('statuses', 0, companyOrgId)\n const { data: lifecycleDict } = useCustomerDictionary('lifecycle-stages', 0, companyOrgId)\n const { data: sourceDict } = useCustomerDictionary('sources', 0, companyOrgId)\n const { data: temperatureDict } = useCustomerDictionary('temperature', 0, companyOrgId)\n const { data: renewalQuarterDict } = useCustomerDictionary('renewal-quarters', 0, companyOrgId)\n\n return (\n <div className=\"rounded-lg border bg-card\">\n {/* Top row: avatar + company info + account manager + actions */}\n <div className=\"flex flex-col gap-4 px-6 pt-6 pb-3 sm:flex-row sm:items-start sm:gap-5\">\n {/* Avatar */}\n <div className=\"flex size-18 shrink-0 items-center justify-center rounded-full bg-muted\">\n <Building2 className=\"size-7 text-muted-foreground\" />\n </div>\n\n {/* Company info */}\n <div className=\"min-w-0 flex-1\">\n <h1 className=\"truncate text-2xl font-bold text-foreground\">{displayName}</h1>\n {subtitle && (\n <p className=\"mt-0.5 text-sm text-muted-foreground\">{subtitle}</p>\n )}\n\n {/* Contact row */}\n <div className=\"mt-1.5 flex flex-wrap items-center gap-x-5 gap-y-1 text-sm text-muted-foreground\">\n {company.primaryPhone && (\n <span className=\"inline-flex items-center gap-1.5\">\n <Phone className=\"size-3.5\" />\n <a href={`tel:${company.primaryPhone}`} className=\"hover:text-foreground\">{company.primaryPhone}</a>\n </span>\n )}\n {company.primaryEmail && (\n <span className=\"inline-flex items-center gap-1.5\">\n <Mail className=\"size-3.5\" />\n <a href={`mailto:${company.primaryEmail}`} className=\"hover:text-foreground\">{company.primaryEmail}</a>\n </span>\n )}\n {profile?.websiteUrl && (\n <a href={profile.websiteUrl.startsWith('http') ? profile.websiteUrl : `https://${profile.websiteUrl}`} target=\"_blank\" rel=\"noreferrer\" className=\"inline-flex items-center gap-1.5 hover:text-foreground\">\n <Globe className=\"size-3.5\" />\n {profile.websiteUrl}\n </a>\n )}\n {locationText && (\n <span className=\"inline-flex items-center gap-1.5\">\n <MapPin className=\"size-3.5\" />\n {locationText}\n </span>\n )}\n </div>\n\n {/* Status badges + temperature + renewal quarter + inline tags */}\n <div className=\"mt-2.5 flex flex-wrap items-center gap-1.5\">\n {company.status && (\n <CompanyDictionaryBadge value={company.status} map={statusDict?.map} />\n )}\n {company.lifecycleStage && (\n <CompanyDictionaryBadge value={company.lifecycleStage} map={lifecycleDict?.map} />\n )}\n {company.source && (\n <CompanyDictionaryBadge value={company.source} map={sourceDict?.map} />\n )}\n {company.temperature && (\n <CompanyDictionaryBadge value={company.temperature} map={temperatureDict?.map} />\n )}\n {company.renewalQuarter && (\n <CompanyDictionaryBadge value={company.renewalQuarter} map={renewalQuarterDict?.map} />\n )}\n {visibleCustomTags.map((tag) => {\n const colorStyle: React.CSSProperties | undefined = tag.color\n ? { color: tag.color, borderColor: tag.color, backgroundColor: `${tag.color}1A` }\n : undefined\n return (\n <Badge\n key={tag.id}\n variant=\"outline\"\n className=\"rounded-sm gap-1.5 text-xs font-medium\"\n style={colorStyle}\n >\n {tag.label}\n </Badge>\n )\n })}\n {hiddenCustomTagsCount > 0 ? (\n <Badge variant=\"outline\" className=\"rounded-sm gap-1.5 text-xs font-medium\">\n +{hiddenCustomTagsCount} {t('customers.companies.detail.header.more', 'more')}\n </Badge>\n ) : null}\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n className=\"h-auto rounded-sm px-2 py-1 text-xs font-medium text-muted-foreground hover:text-foreground\"\n onClick={() => setManageTagsOpen(true)}\n >\n <Pencil className=\"mr-1 size-3\" />\n {t('customers.companies.detail.actions.manageTags', 'Edit tags')}\n </Button>\n </div>\n </div>\n\n {/* Right side: actions */}\n <div className=\"flex w-full shrink-0 flex-col items-start gap-3 sm:w-auto sm:items-end\">\n <div className=\"flex w-full flex-wrap items-center justify-start gap-2 sm:w-auto sm:justify-end\">\n <IconButton\n variant=\"outline\"\n size=\"sm\"\n type=\"button\"\n aria-label={t('customers.companies.detail.actions.delete', 'Delete company')}\n onClick={() => {\n void onDelete()\n }}\n >\n <Trash2 className=\"size-4\" />\n </IconButton>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={onSave}\n disabled={!isDirty || isSaving}\n >\n {t('customers.companies.detail.actions.save', 'Save')}\n </Button>\n </div>\n </div>\n </div>\n\n <CompanyTagsDialog\n open={manageTagsOpen}\n onClose={() => setManageTagsOpen(false)}\n entityId={company.id}\n companyOrganizationId={company.organizationId ?? null}\n companyData={{\n status: company.status,\n lifecycleStage: company.lifecycleStage,\n source: company.source,\n temperature: company.temperature,\n renewalQuarter: company.renewalQuarter,\n industry: profile?.industry ?? null,\n customFields: data.customFields,\n tags: data.tags,\n }}\n onSaved={() => {\n void invalidateCustomerDictionary(queryClient, 'statuses')\n void invalidateCustomerDictionary(queryClient, 'lifecycle-stages')\n void invalidateCustomerDictionary(queryClient, 'sources')\n void invalidateCustomerDictionary(queryClient, 'temperature')\n void invalidateCustomerDictionary(queryClient, 'renewal-quarters')\n onDataReload?.()\n }}\n />\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,123 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { cn } from "@open-mercato/shared/lib/utils";
5
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
6
+ import { Button } from "@open-mercato/ui/primitives/button";
7
+ import {
8
+ Users,
9
+ Handshake,
10
+ Clock,
11
+ History,
12
+ Paperclip
13
+ } from "lucide-react";
14
+ const LEGACY_TAB_MAP = {
15
+ notes: "people",
16
+ activities: "activity-log",
17
+ addresses: "people",
18
+ tasks: "people",
19
+ dashboard: "people",
20
+ "dane-firmy": "people",
21
+ analysis: "people"
22
+ };
23
+ function resolveLegacyTab(tab) {
24
+ if (!tab) return "people";
25
+ if (LEGACY_TAB_MAP[tab]) return LEGACY_TAB_MAP[tab];
26
+ return tab;
27
+ }
28
+ function NewBadge() {
29
+ return /* @__PURE__ */ jsx("span", { className: "ml-1.5 rounded bg-foreground px-1.5 py-0.5 text-overline font-semibold leading-none text-background", children: "NEW" });
30
+ }
31
+ function CountBadge({ count }) {
32
+ if (count <= 0) return null;
33
+ return /* @__PURE__ */ jsx("span", { className: "ml-1.5 rounded-full bg-muted px-1.5 py-0.5 text-xs font-medium leading-none text-muted-foreground", children: count > 999 ? "999+" : count });
34
+ }
35
+ function CompanyDetailTabs({
36
+ activeTab,
37
+ onTabChange,
38
+ injectedTabs = [],
39
+ peopleCount = 0,
40
+ dealsCount = 0,
41
+ activitiesCount = 0,
42
+ filesCount = 0,
43
+ children
44
+ }) {
45
+ const t = useT();
46
+ const builtInTabs = React.useMemo(
47
+ () => [
48
+ {
49
+ id: "people",
50
+ label: t("customers.companies.detail.tabs.people", "People"),
51
+ icon: /* @__PURE__ */ jsx(Users, { className: "size-4" }),
52
+ badge: /* @__PURE__ */ jsx(CountBadge, { count: peopleCount })
53
+ },
54
+ {
55
+ id: "deals",
56
+ label: t("customers.companies.detail.tabs.deals", "Deals"),
57
+ icon: /* @__PURE__ */ jsx(Handshake, { className: "size-4" }),
58
+ badge: /* @__PURE__ */ jsx(CountBadge, { count: dealsCount })
59
+ },
60
+ {
61
+ id: "activity-log",
62
+ label: t("customers.companies.detail.tabs.activityLog", "Activity log"),
63
+ icon: /* @__PURE__ */ jsx(Clock, { className: "size-4" }),
64
+ badge: /* @__PURE__ */ jsx(CountBadge, { count: activitiesCount })
65
+ },
66
+ {
67
+ id: "changelog",
68
+ label: t("customers.companies.detail.tabs.changelog", "Changelog"),
69
+ icon: /* @__PURE__ */ jsx(History, { className: "size-4" }),
70
+ badge: /* @__PURE__ */ jsx(NewBadge, {})
71
+ },
72
+ {
73
+ id: "files",
74
+ label: t("customers.companies.detail.tabs.files", "Files"),
75
+ icon: /* @__PURE__ */ jsx(Paperclip, { className: "size-4" }),
76
+ badge: /* @__PURE__ */ jsx(CountBadge, { count: filesCount })
77
+ }
78
+ ],
79
+ [t, peopleCount, dealsCount, activitiesCount, filesCount]
80
+ );
81
+ const allTabs = React.useMemo(
82
+ () => [
83
+ ...builtInTabs,
84
+ ...injectedTabs.map((tab) => ({
85
+ id: tab.id,
86
+ label: tab.label
87
+ }))
88
+ ],
89
+ [builtInTabs, injectedTabs]
90
+ );
91
+ return /* @__PURE__ */ jsxs("div", { children: [
92
+ /* @__PURE__ */ jsx("div", { className: "border-b", role: "tablist", "aria-label": t("customers.companies.detail.tabs.label", "Company detail sections"), children: /* @__PURE__ */ jsx("nav", { className: "-mb-px flex gap-1 overflow-x-auto px-1", children: allTabs.map((tab) => {
93
+ const isActive = activeTab === tab.id;
94
+ return /* @__PURE__ */ jsxs(
95
+ Button,
96
+ {
97
+ type: "button",
98
+ variant: "ghost",
99
+ size: "sm",
100
+ role: "tab",
101
+ "aria-selected": isActive,
102
+ onClick: () => onTabChange(tab.id),
103
+ className: cn(
104
+ "h-auto shrink-0 rounded-none border-b-2 px-3 py-2.5 hover:bg-transparent",
105
+ isActive ? "border-foreground text-foreground font-semibold" : "border-transparent text-muted-foreground hover:text-foreground"
106
+ ),
107
+ children: [
108
+ tab.icon && /* @__PURE__ */ jsx("span", { className: "mr-1.5", children: tab.icon }),
109
+ tab.label,
110
+ tab.badge
111
+ ]
112
+ },
113
+ tab.id
114
+ );
115
+ }) }) }),
116
+ /* @__PURE__ */ jsx("div", { className: "pt-6", role: "tabpanel", children })
117
+ ] });
118
+ }
119
+ export {
120
+ CompanyDetailTabs,
121
+ resolveLegacyTab
122
+ };
123
+ //# sourceMappingURL=CompanyDetailTabs.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/customers/components/detail/CompanyDetailTabs.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { cn } from '@open-mercato/shared/lib/utils'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Badge } from '@open-mercato/ui/primitives/badge'\nimport {\n Users,\n Handshake,\n Clock,\n History,\n Paperclip,\n} from 'lucide-react'\n\nexport type CompanyTabId =\n | 'people'\n | 'deals'\n | 'activity-log'\n | 'changelog'\n | 'files'\n | string\n\ntype TabDef = {\n id: CompanyTabId\n label: string\n icon?: React.ReactNode\n badge?: React.ReactNode\n}\n\ntype CompanyDetailTabsProps = {\n activeTab: CompanyTabId\n onTabChange: (tab: CompanyTabId) => void\n injectedTabs?: Array<{ id: string; label: string; priority?: number }>\n peopleCount?: number\n dealsCount?: number\n activitiesCount?: number\n filesCount?: number\n children: React.ReactNode\n}\n\nconst LEGACY_TAB_MAP: Record<string, CompanyTabId> = {\n notes: 'people',\n activities: 'activity-log',\n addresses: 'people',\n tasks: 'people',\n dashboard: 'people',\n 'dane-firmy': 'people',\n analysis: 'people',\n}\n\nexport function resolveLegacyTab(tab: string | null | undefined): CompanyTabId {\n if (!tab) return 'people'\n if (LEGACY_TAB_MAP[tab]) return LEGACY_TAB_MAP[tab]\n return tab as CompanyTabId\n}\n\nfunction NewBadge() {\n return (\n <span className=\"ml-1.5 rounded bg-foreground px-1.5 py-0.5 text-overline font-semibold leading-none text-background\">\n NEW\n </span>\n )\n}\n\nfunction CountBadge({ count }: { count: number }) {\n if (count <= 0) return null\n return (\n <span className=\"ml-1.5 rounded-full bg-muted px-1.5 py-0.5 text-xs font-medium leading-none text-muted-foreground\">\n {count > 999 ? '999+' : count}\n </span>\n )\n}\n\nexport function CompanyDetailTabs({\n activeTab,\n onTabChange,\n injectedTabs = [],\n peopleCount = 0,\n dealsCount = 0,\n activitiesCount = 0,\n filesCount = 0,\n children,\n}: CompanyDetailTabsProps) {\n const t = useT()\n\n const builtInTabs: TabDef[] = React.useMemo(\n () => [\n {\n id: 'people',\n label: t('customers.companies.detail.tabs.people', 'People'),\n icon: <Users className=\"size-4\" />,\n badge: <CountBadge count={peopleCount} />,\n },\n {\n id: 'deals',\n label: t('customers.companies.detail.tabs.deals', 'Deals'),\n icon: <Handshake className=\"size-4\" />,\n badge: <CountBadge count={dealsCount} />,\n },\n {\n id: 'activity-log',\n label: t('customers.companies.detail.tabs.activityLog', 'Activity log'),\n icon: <Clock className=\"size-4\" />,\n badge: <CountBadge count={activitiesCount} />,\n },\n {\n id: 'changelog',\n label: t('customers.companies.detail.tabs.changelog', 'Changelog'),\n icon: <History className=\"size-4\" />,\n badge: <NewBadge />,\n },\n {\n id: 'files',\n label: t('customers.companies.detail.tabs.files', 'Files'),\n icon: <Paperclip className=\"size-4\" />,\n badge: <CountBadge count={filesCount} />,\n },\n ],\n [t, peopleCount, dealsCount, activitiesCount, filesCount],\n )\n\n const allTabs: TabDef[] = React.useMemo(\n () => [\n ...builtInTabs,\n ...injectedTabs.map((tab) => ({\n id: tab.id as CompanyTabId,\n label: tab.label,\n })),\n ],\n [builtInTabs, injectedTabs],\n )\n\n return (\n <div>\n {/* Tab navigation */}\n <div className=\"border-b\" role=\"tablist\" aria-label={t('customers.companies.detail.tabs.label', 'Company detail sections')}>\n <nav className=\"-mb-px flex gap-1 overflow-x-auto px-1\">\n {allTabs.map((tab) => {\n const isActive = activeTab === tab.id\n return (\n <Button\n key={tab.id}\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n role=\"tab\"\n aria-selected={isActive}\n onClick={() => onTabChange(tab.id)}\n className={cn(\n 'h-auto shrink-0 rounded-none border-b-2 px-3 py-2.5 hover:bg-transparent',\n isActive\n ? 'border-foreground text-foreground font-semibold'\n : 'border-transparent text-muted-foreground hover:text-foreground',\n )}\n >\n {tab.icon && <span className=\"mr-1.5\">{tab.icon}</span>}\n {tab.label}\n {tab.badge}\n </Button>\n )\n })}\n </nav>\n </div>\n\n {/* Tab content */}\n <div className=\"pt-6\" role=\"tabpanel\">\n {children}\n </div>\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,174 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { EyeOff } from "lucide-react";
5
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
6
+ import { KpiCard } from "@open-mercato/ui/backend/charts/KpiCard";
7
+ import { Button } from "@open-mercato/ui/primitives/button";
8
+ import { IconButton } from "@open-mercato/ui/primitives/icon-button";
9
+ import {
10
+ readJsonFromLocalStorage,
11
+ writeJsonToLocalStorage,
12
+ removeLocalStorageKey
13
+ } from "@open-mercato/shared/lib/browser/safeLocalStorage";
14
+ import { formatCurrency } from "./utils.js";
15
+ const STORAGE_KEY = "om:company-detail-kpi-hidden";
16
+ function sumActiveDeals(deals) {
17
+ return deals.filter((d) => d.status !== "won" && d.status !== "lost" && d.status !== "closed").reduce((sum, d) => {
18
+ const amount = typeof d.valueAmount === "number" ? d.valueAmount : parseFloat(String(d.valueAmount ?? "0"));
19
+ return sum + (Number.isFinite(amount) ? amount : 0);
20
+ }, 0);
21
+ }
22
+ function getActiveDeals(deals) {
23
+ return deals.filter((d) => d.status !== "won" && d.status !== "lost" && d.status !== "closed");
24
+ }
25
+ function computeActivityTrend(interactions) {
26
+ const now = Date.now();
27
+ const weekMs = 7 * 864e5;
28
+ const thisWeek = interactions.filter((i) => {
29
+ const d = i.occurredAt ?? i.scheduledAt;
30
+ return d && now - new Date(d).getTime() < weekMs;
31
+ }).length;
32
+ const lastWeek = interactions.filter((i) => {
33
+ const d = i.occurredAt ?? i.scheduledAt;
34
+ if (!d) return false;
35
+ const diff = now - new Date(d).getTime();
36
+ return diff >= weekMs && diff < weekMs * 2;
37
+ }).length;
38
+ if (lastWeek === 0 && thisWeek === 0) return void 0;
39
+ if (lastWeek === 0) return { value: 100, direction: "up" };
40
+ const pct = (thisWeek - lastWeek) / lastWeek * 100;
41
+ if (Math.abs(pct) < 0.5) return { value: 0, direction: "unchanged" };
42
+ return { value: Math.abs(pct), direction: pct > 0 ? "up" : "down" };
43
+ }
44
+ function computeDealTrend(deals) {
45
+ const active = deals.filter((d) => d.status !== "won" && d.status !== "lost" && d.status !== "closed");
46
+ if (active.length === 0) return void 0;
47
+ const now = Date.now();
48
+ const monthMs = 30 * 864e5;
49
+ const recentDeals = active.filter((d) => d.createdAt && now - new Date(d.createdAt).getTime() < monthMs).length;
50
+ if (recentDeals > 0) return { value: recentDeals * 10, direction: "up" };
51
+ return { value: 0, direction: "unchanged" };
52
+ }
53
+ function CompanyKpiBar({ data }) {
54
+ const t = useT();
55
+ const activeDeals = React.useMemo(() => getActiveDeals(data.deals), [data.deals]);
56
+ const activeDealsValue = React.useMemo(
57
+ () => data.kpis?.activeDealsValue ?? sumActiveDeals(data.deals),
58
+ [data.deals, data.kpis?.activeDealsValue]
59
+ );
60
+ const dealCurrency = data.kpis?.dealCurrency ?? activeDeals[0]?.valueCurrency ?? data.deals[0]?.valueCurrency ?? "PLN";
61
+ const activityTrend = React.useMemo(
62
+ () => data.kpis?.activityTrend ?? computeActivityTrend(data.interactions),
63
+ [data.interactions, data.kpis?.activityTrend]
64
+ );
65
+ const dealTrend = React.useMemo(() => computeDealTrend(data.deals), [data.deals]);
66
+ const ltvValue = React.useMemo(() => {
67
+ if (data.kpis?.ltvValue !== void 0) return data.kpis.ltvValue;
68
+ const wonDeals = data.deals.filter((d) => d.status === "won");
69
+ if (wonDeals.length === 0) return null;
70
+ return wonDeals.reduce((sum, d) => {
71
+ const amt = typeof d.valueAmount === "number" ? d.valueAmount : parseFloat(String(d.valueAmount ?? "0"));
72
+ return sum + (Number.isFinite(amt) ? amt : 0);
73
+ }, 0);
74
+ }, [data.deals, data.kpis?.ltvValue]);
75
+ const clientTenureYears = React.useMemo(() => {
76
+ if (data.kpis?.clientTenureYears !== void 0) return data.kpis.clientTenureYears;
77
+ const allDates = data.interactions.map((i) => i.occurredAt ?? i.scheduledAt ?? i.createdAt).filter(Boolean).map((d) => new Date(d).getTime());
78
+ if (allDates.length === 0) return null;
79
+ const earliest = Math.min(...allDates);
80
+ return Math.floor((Date.now() - earliest) / (365.25 * 864e5));
81
+ }, [data.interactions, data.kpis?.clientTenureYears]);
82
+ const [hiddenTiles, setHiddenTiles] = React.useState(
83
+ () => new Set(readJsonFromLocalStorage(STORAGE_KEY, []))
84
+ );
85
+ const toggleTile = React.useCallback((tileId) => {
86
+ setHiddenTiles((prev) => {
87
+ const next = new Set(prev);
88
+ if (next.has(tileId)) next.delete(tileId);
89
+ else next.add(tileId);
90
+ writeJsonToLocalStorage(STORAGE_KEY, [...next]);
91
+ return next;
92
+ });
93
+ }, []);
94
+ const showAllTiles = React.useCallback(() => {
95
+ setHiddenTiles(/* @__PURE__ */ new Set());
96
+ removeLocalStorageKey(STORAGE_KEY);
97
+ }, []);
98
+ const kpiTiles = React.useMemo(() => [
99
+ {
100
+ id: "activeDeals",
101
+ title: t("customers.companies.dashboard.kpi.activeDeals", "ACTIVE DEALS"),
102
+ value: activeDealsValue,
103
+ trend: dealTrend,
104
+ formatValue: (v) => formatCurrency(v, dealCurrency),
105
+ comparisonLabel: `${data.kpis?.activeDealsCount ?? activeDeals.length} ${(data.kpis?.activeDealsCount ?? activeDeals.length) === 1 ? "pipeline" : "pipelines"}`
106
+ },
107
+ {
108
+ id: "activities",
109
+ title: t("customers.companies.dashboard.kpi.activities", "ACTIVITIES"),
110
+ value: data.kpis?.activityCount ?? data.interactions.length,
111
+ trend: activityTrend,
112
+ comparisonLabel: t("customers.companies.dashboard.kpi.last12months", "last 12 months")
113
+ },
114
+ {
115
+ id: "ltv",
116
+ title: t("customers.companies.dashboard.kpi.ltv", "CUSTOMER VALUE (LTV)"),
117
+ value: ltvValue,
118
+ formatValue: ltvValue !== null ? (v) => formatCurrency(v, dealCurrency) : void 0,
119
+ comparisonLabel: ltvValue !== null ? t("customers.companies.dashboard.kpi.wonDeals", "won deals total") : t("customers.companies.dashboard.kpi.noWonDeals", "No won deals")
120
+ },
121
+ {
122
+ id: "clientSince",
123
+ title: t("customers.companies.dashboard.kpi.clientSince", "CLIENT SINCE"),
124
+ value: clientTenureYears,
125
+ formatValue: clientTenureYears !== null ? (v) => v < 1 ? `< 1 ${t("customers.companies.dashboard.kpi.year", "year")}` : `${v} ${v === 1 ? t("customers.companies.dashboard.kpi.year", "year") : t("customers.companies.dashboard.kpi.years", "years")}` : void 0,
126
+ comparisonLabel: clientTenureYears !== null ? `${data.kpis?.completedDealsCount ?? data.deals.filter((d) => d.status === "won").length} ${t("customers.companies.dashboard.kpi.completedDeals", "completed deals")}` : t("customers.companies.dashboard.kpi.noInteractions", "No interactions yet")
127
+ }
128
+ ], [t, activeDealsValue, dealTrend, dealCurrency, activeDeals.length, activityTrend, ltvValue, clientTenureYears, data.deals, data.interactions.length, data.kpis]);
129
+ const visibleTiles = kpiTiles.filter((tile) => !hiddenTiles.has(tile.id));
130
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
131
+ /* @__PURE__ */ jsx("div", { className: "grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4", children: visibleTiles.map((tile) => /* @__PURE__ */ jsxs("div", { className: "group relative", children: [
132
+ /* @__PURE__ */ jsx(
133
+ KpiCard,
134
+ {
135
+ title: tile.title,
136
+ value: tile.value,
137
+ trend: tile.trend,
138
+ formatValue: tile.formatValue,
139
+ comparisonLabel: tile.comparisonLabel
140
+ }
141
+ ),
142
+ /* @__PURE__ */ jsx(
143
+ IconButton,
144
+ {
145
+ type: "button",
146
+ variant: "ghost",
147
+ size: "xs",
148
+ onClick: () => toggleTile(tile.id),
149
+ className: "absolute right-2 top-2 opacity-0 transition-opacity group-hover:opacity-60",
150
+ "aria-label": t("customers.companies.dashboard.hideTile", "Hide tile"),
151
+ children: /* @__PURE__ */ jsx(EyeOff, { className: "size-3.5" })
152
+ }
153
+ )
154
+ ] }, tile.id)) }),
155
+ hiddenTiles.size > 0 && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
156
+ /* @__PURE__ */ jsx("span", { className: "text-xs text-muted-foreground", children: t("customers.companies.dashboard.hiddenTiles", "{{count}} tiles hidden", { count: hiddenTiles.size }) }),
157
+ /* @__PURE__ */ jsx(
158
+ Button,
159
+ {
160
+ type: "button",
161
+ variant: "ghost",
162
+ size: "sm",
163
+ className: "h-auto px-1.5 py-0.5 text-xs hover:bg-transparent",
164
+ onClick: showAllTiles,
165
+ children: t("customers.companies.dashboard.showAll", "Show all")
166
+ }
167
+ )
168
+ ] })
169
+ ] });
170
+ }
171
+ export {
172
+ CompanyKpiBar
173
+ };
174
+ //# sourceMappingURL=CompanyKpiBar.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/modules/customers/components/detail/CompanyKpiBar.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { EyeOff } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { KpiCard, type KpiTrend } from '@open-mercato/ui/backend/charts/KpiCard'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport {\n readJsonFromLocalStorage,\n writeJsonToLocalStorage,\n removeLocalStorageKey,\n} from '@open-mercato/shared/lib/browser/safeLocalStorage'\nimport type { CompanyOverview, DealSummary, InteractionSummary } from '../formConfig'\nimport { formatCurrency } from './utils'\n\nconst STORAGE_KEY = 'om:company-detail-kpi-hidden'\n\nfunction sumActiveDeals(deals: DealSummary[]): number {\n return deals\n .filter((d) => d.status !== 'won' && d.status !== 'lost' && d.status !== 'closed')\n .reduce((sum, d) => {\n const amount = typeof d.valueAmount === 'number' ? d.valueAmount : parseFloat(String(d.valueAmount ?? '0'))\n return sum + (Number.isFinite(amount) ? amount : 0)\n }, 0)\n}\n\nfunction getActiveDeals(deals: DealSummary[]): DealSummary[] {\n return deals.filter((d) => d.status !== 'won' && d.status !== 'lost' && d.status !== 'closed')\n}\n\nfunction computeActivityTrend(interactions: InteractionSummary[]): KpiTrend | undefined {\n const now = Date.now()\n const weekMs = 7 * 86_400_000\n const thisWeek = interactions.filter((i) => {\n const d = i.occurredAt ?? i.scheduledAt\n return d && now - new Date(d).getTime() < weekMs\n }).length\n const lastWeek = interactions.filter((i) => {\n const d = i.occurredAt ?? i.scheduledAt\n if (!d) return false\n const diff = now - new Date(d).getTime()\n return diff >= weekMs && diff < weekMs * 2\n }).length\n if (lastWeek === 0 && thisWeek === 0) return undefined\n if (lastWeek === 0) return { value: 100, direction: 'up' }\n const pct = ((thisWeek - lastWeek) / lastWeek) * 100\n if (Math.abs(pct) < 0.5) return { value: 0, direction: 'unchanged' }\n return { value: Math.abs(pct), direction: pct > 0 ? 'up' : 'down' }\n}\n\nfunction computeDealTrend(deals: DealSummary[]): KpiTrend | undefined {\n const active = deals.filter((d) => d.status !== 'won' && d.status !== 'lost' && d.status !== 'closed')\n if (active.length === 0) return undefined\n const now = Date.now()\n const monthMs = 30 * 86_400_000\n const recentDeals = active.filter((d) => d.createdAt && now - new Date(d.createdAt).getTime() < monthMs).length\n if (recentDeals > 0) return { value: recentDeals * 10, direction: 'up' }\n return { value: 0, direction: 'unchanged' }\n}\n\ntype CompanyKpiBarProps = {\n data: CompanyOverview\n}\n\nexport function CompanyKpiBar({ data }: CompanyKpiBarProps) {\n const t = useT()\n\n const activeDeals = React.useMemo(() => getActiveDeals(data.deals), [data.deals])\n const activeDealsValue = React.useMemo(\n () => data.kpis?.activeDealsValue ?? sumActiveDeals(data.deals),\n [data.deals, data.kpis?.activeDealsValue],\n )\n const dealCurrency = data.kpis?.dealCurrency ?? activeDeals[0]?.valueCurrency ?? data.deals[0]?.valueCurrency ?? 'PLN'\n const activityTrend = React.useMemo(\n () => data.kpis?.activityTrend ?? computeActivityTrend(data.interactions),\n [data.interactions, data.kpis?.activityTrend],\n )\n const dealTrend = React.useMemo(() => computeDealTrend(data.deals), [data.deals])\n\n const ltvValue = React.useMemo(() => {\n if (data.kpis?.ltvValue !== undefined) return data.kpis.ltvValue\n const wonDeals = data.deals.filter((d) => d.status === 'won')\n if (wonDeals.length === 0) return null\n return wonDeals.reduce((sum, d) => {\n const amt = typeof d.valueAmount === 'number' ? d.valueAmount : parseFloat(String(d.valueAmount ?? '0'))\n return sum + (Number.isFinite(amt) ? amt : 0)\n }, 0)\n }, [data.deals, data.kpis?.ltvValue])\n\n const clientTenureYears = React.useMemo(() => {\n if (data.kpis?.clientTenureYears !== undefined) return data.kpis.clientTenureYears\n const allDates = data.interactions\n .map((i) => i.occurredAt ?? i.scheduledAt ?? i.createdAt)\n .filter(Boolean)\n .map((d) => new Date(d).getTime())\n if (allDates.length === 0) return null\n const earliest = Math.min(...allDates)\n return Math.floor((Date.now() - earliest) / (365.25 * 86_400_000))\n }, [data.interactions, data.kpis?.clientTenureYears])\n\n const [hiddenTiles, setHiddenTiles] = React.useState<Set<string>>(\n () => new Set(readJsonFromLocalStorage<string[]>(STORAGE_KEY, [])),\n )\n\n const toggleTile = React.useCallback((tileId: string) => {\n setHiddenTiles((prev) => {\n const next = new Set(prev)\n if (next.has(tileId)) next.delete(tileId)\n else next.add(tileId)\n writeJsonToLocalStorage(STORAGE_KEY, [...next])\n return next\n })\n }, [])\n\n const showAllTiles = React.useCallback(() => {\n setHiddenTiles(new Set())\n removeLocalStorageKey(STORAGE_KEY)\n }, [])\n\n const kpiTiles = React.useMemo(() => [\n {\n id: 'activeDeals',\n title: t('customers.companies.dashboard.kpi.activeDeals', 'ACTIVE DEALS'),\n value: activeDealsValue,\n trend: dealTrend,\n formatValue: (v: number) => formatCurrency(v, dealCurrency),\n comparisonLabel: `${data.kpis?.activeDealsCount ?? activeDeals.length} ${(data.kpis?.activeDealsCount ?? activeDeals.length) === 1 ? 'pipeline' : 'pipelines'}`,\n },\n {\n id: 'activities',\n title: t('customers.companies.dashboard.kpi.activities', 'ACTIVITIES'),\n value: data.kpis?.activityCount ?? data.interactions.length,\n trend: activityTrend,\n comparisonLabel: t('customers.companies.dashboard.kpi.last12months', 'last 12 months'),\n },\n {\n id: 'ltv',\n title: t('customers.companies.dashboard.kpi.ltv', 'CUSTOMER VALUE (LTV)'),\n value: ltvValue,\n formatValue: ltvValue !== null ? (v: number) => formatCurrency(v, dealCurrency) : undefined,\n comparisonLabel: ltvValue !== null\n ? t('customers.companies.dashboard.kpi.wonDeals', 'won deals total')\n : t('customers.companies.dashboard.kpi.noWonDeals', 'No won deals'),\n },\n {\n id: 'clientSince',\n title: t('customers.companies.dashboard.kpi.clientSince', 'CLIENT SINCE'),\n value: clientTenureYears,\n formatValue: clientTenureYears !== null\n ? (v: number) => v < 1\n ? `< 1 ${t('customers.companies.dashboard.kpi.year', 'year')}`\n : `${v} ${v === 1 ? t('customers.companies.dashboard.kpi.year', 'year') : t('customers.companies.dashboard.kpi.years', 'years')}`\n : undefined,\n comparisonLabel: clientTenureYears !== null\n ? `${data.kpis?.completedDealsCount ?? data.deals.filter((d) => d.status === 'won').length} ${t('customers.companies.dashboard.kpi.completedDeals', 'completed deals')}`\n : t('customers.companies.dashboard.kpi.noInteractions', 'No interactions yet'),\n },\n ], [t, activeDealsValue, dealTrend, dealCurrency, activeDeals.length, activityTrend, ltvValue, clientTenureYears, data.deals, data.interactions.length, data.kpis])\n\n const visibleTiles = kpiTiles.filter((tile) => !hiddenTiles.has(tile.id))\n\n return (\n <div className=\"space-y-2\">\n <div className=\"grid grid-cols-1 gap-4 sm:grid-cols-2 xl:grid-cols-4\">\n {visibleTiles.map((tile) => (\n <div key={tile.id} className=\"group relative\">\n <KpiCard\n title={tile.title}\n value={tile.value}\n trend={tile.trend}\n formatValue={tile.formatValue}\n comparisonLabel={tile.comparisonLabel}\n />\n <IconButton\n type=\"button\"\n variant=\"ghost\"\n size=\"xs\"\n onClick={() => toggleTile(tile.id)}\n className=\"absolute right-2 top-2 opacity-0 transition-opacity group-hover:opacity-60\"\n aria-label={t('customers.companies.dashboard.hideTile', 'Hide tile')}\n >\n <EyeOff className=\"size-3.5\" />\n </IconButton>\n </div>\n ))}\n </div>\n {hiddenTiles.size > 0 && (\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {t('customers.companies.dashboard.hiddenTiles', '{{count}} tiles hidden', { count: hiddenTiles.size })}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"h-auto px-1.5 py-0.5 text-xs hover:bg-transparent\"\n onClick={showAllTiles}\n >\n {t('customers.companies.dashboard.showAll', 'Show all')}\n </Button>\n </div>\n )}\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }