@open-mercato/core 0.6.5-develop.4534.1.b459babe6d → 0.6.5-develop.4544.1.71c003c861

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 (633) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/AGENTS.md +5 -0
  3. package/dist/generated/entities/role/index.js +3 -1
  4. package/dist/generated/entities/role/index.js.map +2 -2
  5. package/dist/generated/entities/user/index.js +3 -1
  6. package/dist/generated/entities/user/index.js.map +2 -2
  7. package/dist/generated/entity-fields-registry.js +2 -0
  8. package/dist/generated/entity-fields-registry.js.map +2 -2
  9. package/dist/helpers/integration/optimisticLockUi.js +104 -0
  10. package/dist/helpers/integration/optimisticLockUi.js.map +7 -0
  11. package/dist/helpers/integration/salesFixtures.js +17 -0
  12. package/dist/helpers/integration/salesFixtures.js.map +2 -2
  13. package/dist/modules/api_keys/backend/api-keys/page.js +9 -5
  14. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  15. package/dist/modules/attachments/components/AttachmentPartitionSettings.js +17 -9
  16. package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
  17. package/dist/modules/auth/api/roles/acl/route.js +32 -13
  18. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  19. package/dist/modules/auth/api/roles/route.js +3 -1
  20. package/dist/modules/auth/api/roles/route.js.map +2 -2
  21. package/dist/modules/auth/api/sidebar/preferences/route.js +71 -3
  22. package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
  23. package/dist/modules/auth/api/users/acl/route.js +42 -19
  24. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  25. package/dist/modules/auth/api/users/route.js +3 -1
  26. package/dist/modules/auth/api/users/route.js.map +2 -2
  27. package/dist/modules/auth/backend/roles/[id]/edit/page.js +24 -4
  28. package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
  29. package/dist/modules/auth/backend/roles/page.js +8 -4
  30. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  31. package/dist/modules/auth/backend/users/[id]/edit/page.js +27 -5
  32. package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
  33. package/dist/modules/auth/backend/users/page.js +6 -2
  34. package/dist/modules/auth/backend/users/page.js.map +2 -2
  35. package/dist/modules/auth/components/AclEditor.js +3 -1
  36. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  37. package/dist/modules/auth/data/entities.js +6 -0
  38. package/dist/modules/auth/data/entities.js.map +2 -2
  39. package/dist/modules/auth/services/sidebarPreferencesService.js +32 -4
  40. package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
  41. package/dist/modules/business_rules/api/rules/route.js +28 -0
  42. package/dist/modules/business_rules/api/rules/route.js.map +2 -2
  43. package/dist/modules/business_rules/api/sets/route.js +28 -0
  44. package/dist/modules/business_rules/api/sets/route.js.map +2 -2
  45. package/dist/modules/business_rules/backend/rules/[id]/page.js +11 -4
  46. package/dist/modules/business_rules/backend/rules/[id]/page.js.map +3 -3
  47. package/dist/modules/business_rules/backend/rules/page.js +20 -11
  48. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  49. package/dist/modules/business_rules/backend/sets/[id]/page.js +11 -4
  50. package/dist/modules/business_rules/backend/sets/[id]/page.js.map +2 -2
  51. package/dist/modules/business_rules/backend/sets/page.js +20 -11
  52. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  53. package/dist/modules/catalog/api/categories/route.js +2 -0
  54. package/dist/modules/catalog/api/categories/route.js.map +2 -2
  55. package/dist/modules/catalog/api/products/route.js +2 -1
  56. package/dist/modules/catalog/api/products/route.js.map +2 -2
  57. package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +2 -0
  58. package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
  59. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +94 -40
  60. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  61. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +37 -8
  62. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
  63. package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js.map +2 -2
  64. package/dist/modules/catalog/commands/variants.js +32 -31
  65. package/dist/modules/catalog/commands/variants.js.map +2 -2
  66. package/dist/modules/catalog/components/PriceKindSettings.js +12 -5
  67. package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
  68. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  69. package/dist/modules/catalog/components/products/ProductMediaManager.js.map +2 -2
  70. package/dist/modules/catalog/components/products/ProductsDataTable.js +5 -3
  71. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  72. package/dist/modules/catalog/components/products/productForm.js.map +2 -2
  73. package/dist/modules/catalog/components/products/variantForm.js +2 -1
  74. package/dist/modules/catalog/components/products/variantForm.js.map +2 -2
  75. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +5 -0
  76. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +2 -2
  77. package/dist/modules/currencies/backend/currencies/[id]/page.js +6 -3
  78. package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
  79. package/dist/modules/currencies/backend/currencies/page.js +18 -11
  80. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  81. package/dist/modules/currencies/backend/exchange-rates/[id]/page.js +1 -0
  82. package/dist/modules/currencies/backend/exchange-rates/[id]/page.js.map +2 -2
  83. package/dist/modules/currencies/backend/exchange-rates/page.js +10 -6
  84. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  85. package/dist/modules/currencies/commands/currencies.js +7 -5
  86. package/dist/modules/currencies/commands/currencies.js.map +2 -2
  87. package/dist/modules/currencies/components/CurrencyFetchingConfig.js +26 -19
  88. package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
  89. package/dist/modules/customer_accounts/api/admin/roles/[id].js +28 -5
  90. package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
  91. package/dist/modules/customer_accounts/api/admin/roles.js +4 -2
  92. package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
  93. package/dist/modules/customer_accounts/api/admin/users/[id].js +28 -5
  94. package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
  95. package/dist/modules/customer_accounts/api/admin/users.js +2 -0
  96. package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
  97. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +16 -8
  98. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
  99. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +8 -4
  100. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  101. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +8 -4
  102. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +2 -2
  103. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +29 -18
  104. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  105. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +18 -11
  106. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  107. package/dist/modules/customers/api/companies/route.js +13 -2
  108. package/dist/modules/customers/api/companies/route.js.map +2 -2
  109. package/dist/modules/customers/api/deals/route.js +2 -0
  110. package/dist/modules/customers/api/deals/route.js.map +2 -2
  111. package/dist/modules/customers/api/people/route.js +11 -2
  112. package/dist/modules/customers/api/people/route.js.map +2 -2
  113. package/dist/modules/customers/api/todos/route.js +1 -0
  114. package/dist/modules/customers/api/todos/route.js.map +2 -2
  115. package/dist/modules/customers/backend/config/customers/deals/page.js.map +2 -2
  116. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +34 -21
  117. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
  118. package/dist/modules/customers/backend/customers/companies/[id]/page.js +45 -27
  119. package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
  120. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  121. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +22 -5
  122. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  123. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +30 -8
  124. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +2 -2
  125. package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -0
  126. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  127. package/dist/modules/customers/backend/customers/deals/page.js +16 -6
  128. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  129. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +62 -39
  130. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  131. package/dist/modules/customers/backend/customers/people/[id]/page.js +41 -26
  132. package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
  133. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  134. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +50 -23
  135. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  136. package/dist/modules/customers/commands/addresses.js +16 -14
  137. package/dist/modules/customers/commands/addresses.js.map +2 -2
  138. package/dist/modules/customers/commands/companies.js +1 -1
  139. package/dist/modules/customers/commands/companies.js.map +2 -2
  140. package/dist/modules/customers/commands/interactions.js +41 -4
  141. package/dist/modules/customers/commands/interactions.js.map +2 -2
  142. package/dist/modules/customers/commands/people.js +1 -1
  143. package/dist/modules/customers/commands/people.js.map +2 -2
  144. package/dist/modules/customers/commands/personCompanyLinks.js +8 -5
  145. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  146. package/dist/modules/customers/commands/pipeline-stages.js +13 -11
  147. package/dist/modules/customers/commands/pipeline-stages.js.map +3 -3
  148. package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
  149. package/dist/modules/customers/components/DictionarySettings.js +20 -13
  150. package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
  151. package/dist/modules/customers/components/DictionarySortSettings.js +4 -0
  152. package/dist/modules/customers/components/DictionarySortSettings.js.map +2 -2
  153. package/dist/modules/customers/components/PipelineSettings.js +38 -23
  154. package/dist/modules/customers/components/PipelineSettings.js.map +2 -2
  155. package/dist/modules/customers/components/detail/ActivityTimeline.js +1 -1
  156. package/dist/modules/customers/components/detail/ActivityTimeline.js.map +2 -2
  157. package/dist/modules/customers/components/detail/AddressesSection.js +4 -0
  158. package/dist/modules/customers/components/detail/AddressesSection.js.map +2 -2
  159. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +28 -22
  160. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  161. package/dist/modules/customers/components/detail/DealsSection.js +36 -24
  162. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  163. package/dist/modules/customers/components/detail/EmailCardActions.js +5 -0
  164. package/dist/modules/customers/components/detail/EmailCardActions.js.map +2 -2
  165. package/dist/modules/customers/components/detail/EntityTagsDialog.js +7 -0
  166. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  167. package/dist/modules/customers/components/detail/ManageTagsDialog.js +34 -22
  168. package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
  169. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +41 -29
  170. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
  171. package/dist/modules/customers/components/detail/RoleAssignmentRow.js +14 -8
  172. package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +2 -2
  173. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +14 -6
  174. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
  175. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +29 -13
  176. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +2 -2
  177. package/dist/modules/customers/components/detail/hooks/useInteractions.js +77 -35
  178. package/dist/modules/customers/components/detail/hooks/useInteractions.js.map +2 -2
  179. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +25 -17
  180. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
  181. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  182. package/dist/modules/customers/components/formConfig.js.map +2 -2
  183. package/dist/modules/customers/data/guards.js +66 -0
  184. package/dist/modules/customers/data/guards.js.map +7 -0
  185. package/dist/modules/customers/di.js +37 -0
  186. package/dist/modules/customers/di.js.map +2 -2
  187. package/dist/modules/customers/lib/todoCompatibility.js +11 -0
  188. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  189. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
  190. package/dist/modules/data_sync/api/options.js +4 -4
  191. package/dist/modules/data_sync/api/options.js.map +2 -2
  192. package/dist/modules/data_sync/api/schedules/route.js +9 -1
  193. package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
  194. package/dist/modules/data_sync/backend/data-sync/page.js +17 -8
  195. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  196. package/dist/modules/data_sync/components/IntegrationScheduleTab.js +43 -22
  197. package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
  198. package/dist/modules/data_sync/lib/sync-schedule-service.js +9 -0
  199. package/dist/modules/data_sync/lib/sync-schedule-service.js.map +2 -2
  200. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +8 -1
  201. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  202. package/dist/modules/dictionaries/api/[dictionaryId]/route.js +17 -1
  203. package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
  204. package/dist/modules/dictionaries/components/DictionariesManager.js +31 -10
  205. package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
  206. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +28 -15
  207. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
  208. package/dist/modules/directory/api/organizations/route.js +3 -0
  209. package/dist/modules/directory/api/organizations/route.js.map +2 -2
  210. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +2 -0
  211. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
  212. package/dist/modules/directory/backend/directory/organizations/page.js +9 -5
  213. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  214. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +7 -3
  215. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
  216. package/dist/modules/directory/backend/directory/tenants/page.js +8 -4
  217. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  218. package/dist/modules/directory/commands/organizations.js +7 -2
  219. package/dist/modules/directory/commands/organizations.js.map +2 -2
  220. package/dist/modules/entities/api/records.js +66 -0
  221. package/dist/modules/entities/api/records.js.map +2 -2
  222. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +1 -0
  223. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
  224. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +8 -4
  225. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  226. package/dist/modules/entities/lib/helpers.js +17 -0
  227. package/dist/modules/entities/lib/helpers.js.map +2 -2
  228. package/dist/modules/feature_toggles/api/global/[id]/override/route.js +2 -1
  229. package/dist/modules/feature_toggles/api/global/[id]/override/route.js.map +2 -2
  230. package/dist/modules/feature_toggles/api/overrides/route.js +15 -0
  231. package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
  232. package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js +15 -14
  233. package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js.map +2 -2
  234. package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js +20 -12
  235. package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js.map +2 -2
  236. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +6 -2
  237. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  238. package/dist/modules/feature_toggles/components/formConfig.js +2 -1
  239. package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
  240. package/dist/modules/feature_toggles/components/overrideFormConfig.js +5 -1
  241. package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
  242. package/dist/modules/feature_toggles/data/validators.js +7 -4
  243. package/dist/modules/feature_toggles/data/validators.js.map +2 -2
  244. package/dist/modules/inbox_ops/api/settings/route.js +17 -2
  245. package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
  246. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +13 -8
  247. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
  248. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +9 -4
  249. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
  250. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +18 -11
  251. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  252. package/dist/modules/integrations/backend/integrations/page.js +12 -8
  253. package/dist/modules/integrations/backend/integrations/page.js.map +2 -2
  254. package/dist/modules/messages/commands/messages.js +13 -10
  255. package/dist/modules/messages/commands/messages.js.map +2 -2
  256. package/dist/modules/perspectives/api/[tableId]/route.js +39 -30
  257. package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
  258. package/dist/modules/perspectives/services/perspectiveService.js +7 -0
  259. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  260. package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js +6 -14
  261. package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js.map +3 -3
  262. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +4 -2
  263. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  264. package/dist/modules/planner/components/AvailabilityRuleSetForm.js +2 -0
  265. package/dist/modules/planner/components/AvailabilityRuleSetForm.js.map +2 -2
  266. package/dist/modules/planner/components/AvailabilityRulesEditor.js +36 -11
  267. package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
  268. package/dist/modules/planner/components/AvailabilitySchedule.js +9 -5
  269. package/dist/modules/planner/components/AvailabilitySchedule.js.map +2 -2
  270. package/dist/modules/query_index/lib/engine.js +19 -0
  271. package/dist/modules/query_index/lib/engine.js.map +2 -2
  272. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +1 -0
  273. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +2 -2
  274. package/dist/modules/resources/backend/resources/resource-types/page.js +4 -2
  275. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  276. package/dist/modules/resources/backend/resources/resources/[id]/page.js +14 -3
  277. package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
  278. package/dist/modules/resources/backend/resources/resources/page.js +8 -4
  279. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  280. package/dist/modules/resources/components/ResourceCrudForm.js +2 -0
  281. package/dist/modules/resources/components/ResourceCrudForm.js.map +2 -2
  282. package/dist/modules/resources/components/ResourceTypeCrudForm.js +1 -0
  283. package/dist/modules/resources/components/ResourceTypeCrudForm.js.map +2 -2
  284. package/dist/modules/sales/api/documents/factory.js +7 -2
  285. package/dist/modules/sales/api/documents/factory.js.map +2 -2
  286. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +3 -1
  287. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
  288. package/dist/modules/sales/backend/sales/channels/offers/page.js +13 -4
  289. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  290. package/dist/modules/sales/backend/sales/channels/page.js +16 -4
  291. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  292. package/dist/modules/sales/backend/sales/documents/[id]/page.js +68 -22
  293. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  294. package/dist/modules/sales/backend/sales/documents/create/page.js.map +2 -2
  295. package/dist/modules/sales/commands/documentAddresses.js +181 -2
  296. package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
  297. package/dist/modules/sales/commands/documents.js +29 -1
  298. package/dist/modules/sales/commands/documents.js.map +2 -2
  299. package/dist/modules/sales/commands/returns.js +12 -2
  300. package/dist/modules/sales/commands/returns.js.map +2 -2
  301. package/dist/modules/sales/commands/shared.js +15 -0
  302. package/dist/modules/sales/commands/shared.js.map +2 -2
  303. package/dist/modules/sales/commands/shipments.js +4 -1
  304. package/dist/modules/sales/commands/shipments.js.map +2 -2
  305. package/dist/modules/sales/components/AdjustmentKindSettings.js +19 -11
  306. package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
  307. package/dist/modules/sales/components/DocumentNumberSettings.js.map +2 -2
  308. package/dist/modules/sales/components/OrderEditingSettings.js.map +2 -2
  309. package/dist/modules/sales/components/PaymentMethodsSettings.js +12 -4
  310. package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
  311. package/dist/modules/sales/components/ShippingMethodsSettings.js +12 -4
  312. package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
  313. package/dist/modules/sales/components/StatusSettings.js +18 -11
  314. package/dist/modules/sales/components/StatusSettings.js.map +2 -2
  315. package/dist/modules/sales/components/TaxRatesSettings.js +12 -4
  316. package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
  317. package/dist/modules/sales/components/channels/ChannelOfferForm.js +47 -16
  318. package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
  319. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +8 -4
  320. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  321. package/dist/modules/sales/components/documents/AddressesSection.js +44 -25
  322. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  323. package/dist/modules/sales/components/documents/AdjustmentsSection.js +43 -23
  324. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  325. package/dist/modules/sales/components/documents/ItemsSection.js +22 -13
  326. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  327. package/dist/modules/sales/components/documents/LineItemDialog.js +23 -10
  328. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  329. package/dist/modules/sales/components/documents/PaymentDialog.js +29 -14
  330. package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
  331. package/dist/modules/sales/components/documents/PaymentsSection.js +20 -10
  332. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  333. package/dist/modules/sales/components/documents/ReturnDialog.js +26 -17
  334. package/dist/modules/sales/components/documents/ReturnDialog.js.map +2 -2
  335. package/dist/modules/sales/components/documents/ReturnsSection.js +3 -1
  336. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  337. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +10 -5
  338. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  339. package/dist/modules/sales/components/documents/ShipmentDialog.js +21 -7
  340. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  341. package/dist/modules/sales/components/documents/ShipmentsSection.js +19 -10
  342. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  343. package/dist/modules/sales/components/documents/optimisticLock.js +27 -0
  344. package/dist/modules/sales/components/documents/optimisticLock.js.map +7 -0
  345. package/dist/modules/sales/di.js +18 -0
  346. package/dist/modules/sales/di.js.map +2 -2
  347. package/dist/modules/staff/api/job-histories.js +11 -2
  348. package/dist/modules/staff/api/job-histories.js.map +2 -2
  349. package/dist/modules/staff/api/timesheets/time-entries/route.js +11 -4
  350. package/dist/modules/staff/api/timesheets/time-entries/route.js.map +2 -2
  351. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +13 -8
  352. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
  353. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +2 -1
  354. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
  355. package/dist/modules/staff/backend/staff/team-members/[id]/page.js +7 -4
  356. package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
  357. package/dist/modules/staff/backend/staff/team-members/page.js +4 -2
  358. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  359. package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +1 -0
  360. package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
  361. package/dist/modules/staff/backend/staff/team-roles/page.js +4 -2
  362. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  363. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +5 -2
  364. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  365. package/dist/modules/staff/backend/staff/teams/page.js +12 -3
  366. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  367. package/dist/modules/staff/backend/staff/timesheets/page.js +4 -1
  368. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  369. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +2 -2
  370. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +12 -3
  371. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  372. package/dist/modules/staff/commands/job-histories.js +40 -3
  373. package/dist/modules/staff/commands/job-histories.js.map +2 -2
  374. package/dist/modules/staff/components/LeaveRequestForm.js +1 -0
  375. package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
  376. package/dist/modules/staff/components/TeamForm.js +1 -0
  377. package/dist/modules/staff/components/TeamForm.js.map +2 -2
  378. package/dist/modules/staff/components/TeamMemberForm.js +1 -0
  379. package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
  380. package/dist/modules/staff/components/TeamRoleForm.js +1 -0
  381. package/dist/modules/staff/components/TeamRoleForm.js.map +2 -2
  382. package/dist/modules/staff/components/detail/JobHistorySection.js +20 -7
  383. package/dist/modules/staff/components/detail/JobHistorySection.js.map +2 -2
  384. package/dist/modules/staff/data/validators.js +7 -1
  385. package/dist/modules/staff/data/validators.js.map +2 -2
  386. package/dist/modules/staff/lib/leaveRequestHelpers.js +2 -1
  387. package/dist/modules/staff/lib/leaveRequestHelpers.js.map +2 -2
  388. package/dist/modules/translations/components/TranslationManager.js +12 -8
  389. package/dist/modules/translations/components/TranslationManager.js.map +2 -2
  390. package/dist/modules/workflows/api/definitions/[id]/route.js +106 -0
  391. package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
  392. package/dist/modules/workflows/backend/definitions/[id]/page.js +11 -3
  393. package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
  394. package/dist/modules/workflows/backend/definitions/page.js +19 -8
  395. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  396. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +29 -16
  397. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  398. package/dist/modules/workflows/components/formConfig.js +4 -1
  399. package/dist/modules/workflows/components/formConfig.js.map +2 -2
  400. package/dist/modules/workflows/di.js +12 -0
  401. package/dist/modules/workflows/di.js.map +2 -2
  402. package/generated/entities/role/index.ts +1 -0
  403. package/generated/entities/user/index.ts +1 -0
  404. package/generated/entity-fields-registry.ts +2 -0
  405. package/jest.setup.ts +17 -0
  406. package/package.json +8 -7
  407. package/src/helpers/integration/optimisticLockUi.ts +172 -0
  408. package/src/helpers/integration/salesFixtures.ts +29 -0
  409. package/src/modules/api_keys/backend/api-keys/page.tsx +10 -5
  410. package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +19 -9
  411. package/src/modules/auth/api/roles/acl/route.ts +37 -11
  412. package/src/modules/auth/api/roles/route.ts +2 -0
  413. package/src/modules/auth/api/sidebar/preferences/route.ts +73 -0
  414. package/src/modules/auth/api/users/acl/route.ts +46 -18
  415. package/src/modules/auth/api/users/route.ts +2 -0
  416. package/src/modules/auth/backend/roles/[id]/edit/page.tsx +29 -4
  417. package/src/modules/auth/backend/roles/page.tsx +9 -4
  418. package/src/modules/auth/backend/users/[id]/edit/page.tsx +37 -4
  419. package/src/modules/auth/backend/users/page.tsx +7 -2
  420. package/src/modules/auth/components/AclEditor.tsx +10 -1
  421. package/src/modules/auth/data/entities.ts +7 -1
  422. package/src/modules/auth/services/sidebarPreferencesService.ts +38 -4
  423. package/src/modules/business_rules/api/rules/route.ts +30 -0
  424. package/src/modules/business_rules/api/sets/route.ts +30 -0
  425. package/src/modules/business_rules/backend/rules/[id]/page.tsx +16 -4
  426. package/src/modules/business_rules/backend/rules/page.tsx +20 -11
  427. package/src/modules/business_rules/backend/sets/[id]/page.tsx +16 -4
  428. package/src/modules/business_rules/backend/sets/page.tsx +20 -11
  429. package/src/modules/catalog/api/categories/route.ts +3 -0
  430. package/src/modules/catalog/api/products/route.ts +4 -0
  431. package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +5 -0
  432. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +112 -35
  433. package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +56 -7
  434. package/src/modules/catalog/backend/catalog/products/optionSchemaClient.ts +2 -0
  435. package/src/modules/catalog/commands/variants.ts +32 -32
  436. package/src/modules/catalog/components/PriceKindSettings.tsx +20 -7
  437. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +1 -0
  438. package/src/modules/catalog/components/products/ProductMediaManager.tsx +2 -0
  439. package/src/modules/catalog/components/products/ProductsDataTable.tsx +8 -4
  440. package/src/modules/catalog/components/products/productForm.ts +3 -0
  441. package/src/modules/catalog/components/products/variantForm.ts +9 -0
  442. package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +5 -0
  443. package/src/modules/currencies/backend/currencies/[id]/page.tsx +13 -6
  444. package/src/modules/currencies/backend/currencies/page.tsx +18 -11
  445. package/src/modules/currencies/backend/exchange-rates/[id]/page.tsx +3 -0
  446. package/src/modules/currencies/backend/exchange-rates/page.tsx +10 -6
  447. package/src/modules/currencies/commands/currencies.ts +10 -5
  448. package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +31 -21
  449. package/src/modules/customer_accounts/api/admin/roles/[id].ts +35 -5
  450. package/src/modules/customer_accounts/api/admin/roles.ts +2 -0
  451. package/src/modules/customer_accounts/api/admin/users/[id].ts +38 -5
  452. package/src/modules/customer_accounts/api/admin/users.ts +2 -0
  453. package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +34 -20
  454. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +9 -4
  455. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +11 -4
  456. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +28 -17
  457. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +19 -11
  458. package/src/modules/customers/AGENTS.md +2 -2
  459. package/src/modules/customers/api/companies/route.ts +14 -1
  460. package/src/modules/customers/api/deals/route.ts +3 -0
  461. package/src/modules/customers/api/people/route.ts +12 -1
  462. package/src/modules/customers/api/todos/route.ts +1 -0
  463. package/src/modules/customers/backend/config/customers/deals/page.tsx +1 -0
  464. package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +36 -21
  465. package/src/modules/customers/backend/customers/companies/[id]/page.tsx +52 -27
  466. package/src/modules/customers/backend/customers/companies/page.tsx +2 -0
  467. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +27 -5
  468. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +39 -7
  469. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +1 -0
  470. package/src/modules/customers/backend/customers/deals/page.tsx +18 -6
  471. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +64 -39
  472. package/src/modules/customers/backend/customers/people/[id]/page.tsx +46 -26
  473. package/src/modules/customers/backend/customers/people/page.tsx +2 -0
  474. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +84 -24
  475. package/src/modules/customers/commands/addresses.ts +16 -14
  476. package/src/modules/customers/commands/companies.ts +3 -1
  477. package/src/modules/customers/commands/interactions.ts +50 -4
  478. package/src/modules/customers/commands/people.ts +2 -1
  479. package/src/modules/customers/commands/personCompanyLinks.ts +8 -5
  480. package/src/modules/customers/commands/pipeline-stages.ts +16 -16
  481. package/src/modules/customers/components/AddressFormatSettings.tsx +1 -0
  482. package/src/modules/customers/components/DictionarySettings.tsx +18 -13
  483. package/src/modules/customers/components/DictionarySortSettings.tsx +4 -0
  484. package/src/modules/customers/components/PipelineSettings.tsx +42 -21
  485. package/src/modules/customers/components/detail/ActivityTimeline.tsx +3 -3
  486. package/src/modules/customers/components/detail/AddressesSection.tsx +4 -0
  487. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +2 -0
  488. package/src/modules/customers/components/detail/DealsSection.tsx +4 -0
  489. package/src/modules/customers/components/detail/EmailCardActions.tsx +5 -0
  490. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +7 -0
  491. package/src/modules/customers/components/detail/ManageTagsDialog.tsx +4 -0
  492. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +4 -0
  493. package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +2 -0
  494. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +23 -7
  495. package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +25 -15
  496. package/src/modules/customers/components/detail/hooks/useInteractions.ts +76 -35
  497. package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +30 -17
  498. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +2 -0
  499. package/src/modules/customers/components/detail/types.ts +1 -0
  500. package/src/modules/customers/components/formConfig.tsx +2 -0
  501. package/src/modules/customers/data/guards.ts +67 -0
  502. package/src/modules/customers/di.ts +66 -0
  503. package/src/modules/customers/i18n/de.json +2 -0
  504. package/src/modules/customers/i18n/en.json +2 -0
  505. package/src/modules/customers/i18n/es.json +2 -0
  506. package/src/modules/customers/i18n/pl.json +2 -0
  507. package/src/modules/customers/lib/todoCompatibility.ts +14 -0
  508. package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +2 -0
  509. package/src/modules/data_sync/api/options.ts +7 -4
  510. package/src/modules/data_sync/api/schedules/route.ts +9 -1
  511. package/src/modules/data_sync/backend/data-sync/page.tsx +18 -5
  512. package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +46 -19
  513. package/src/modules/data_sync/lib/sync-schedule-service.ts +11 -0
  514. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +8 -1
  515. package/src/modules/dictionaries/api/[dictionaryId]/route.ts +23 -0
  516. package/src/modules/dictionaries/components/DictionariesManager.tsx +32 -9
  517. package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +30 -14
  518. package/src/modules/dictionaries/i18n/de.json +1 -0
  519. package/src/modules/dictionaries/i18n/en.json +1 -0
  520. package/src/modules/dictionaries/i18n/es.json +1 -0
  521. package/src/modules/dictionaries/i18n/pl.json +1 -0
  522. package/src/modules/directory/api/organizations/route.ts +3 -0
  523. package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +8 -0
  524. package/src/modules/directory/backend/directory/organizations/page.tsx +10 -5
  525. package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +16 -5
  526. package/src/modules/directory/backend/directory/tenants/page.tsx +8 -4
  527. package/src/modules/directory/commands/organizations.ts +7 -4
  528. package/src/modules/entities/api/records.ts +99 -0
  529. package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +7 -0
  530. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +8 -4
  531. package/src/modules/entities/lib/helpers.ts +17 -0
  532. package/src/modules/feature_toggles/api/global/[id]/override/route.ts +1 -0
  533. package/src/modules/feature_toggles/api/overrides/route.ts +19 -0
  534. package/src/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.tsx +19 -13
  535. package/src/modules/feature_toggles/components/FeatureToggleOverrideCard.tsx +22 -12
  536. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +7 -2
  537. package/src/modules/feature_toggles/components/formConfig.tsx +2 -1
  538. package/src/modules/feature_toggles/components/overrideFormConfig.tsx +10 -1
  539. package/src/modules/feature_toggles/data/validators.ts +11 -3
  540. package/src/modules/inbox_ops/api/settings/route.ts +18 -0
  541. package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +15 -10
  542. package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +9 -4
  543. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +20 -11
  544. package/src/modules/integrations/backend/integrations/page.tsx +13 -8
  545. package/src/modules/messages/commands/messages.ts +27 -15
  546. package/src/modules/perspectives/api/[tableId]/route.ts +11 -2
  547. package/src/modules/perspectives/services/perspectiveService.ts +13 -1
  548. package/src/modules/planner/backend/planner/availability-rulesets/[id]/page.tsx +16 -14
  549. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +6 -3
  550. package/src/modules/planner/components/AvailabilityRuleSetForm.tsx +3 -0
  551. package/src/modules/planner/components/AvailabilityRulesEditor.tsx +58 -15
  552. package/src/modules/planner/components/AvailabilitySchedule.tsx +22 -7
  553. package/src/modules/query_index/lib/engine.ts +34 -0
  554. package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +7 -1
  555. package/src/modules/resources/backend/resources/resource-types/page.tsx +6 -3
  556. package/src/modules/resources/backend/resources/resources/[id]/page.tsx +23 -3
  557. package/src/modules/resources/backend/resources/resources/page.tsx +15 -4
  558. package/src/modules/resources/components/ResourceCrudForm.tsx +3 -0
  559. package/src/modules/resources/components/ResourceTypeCrudForm.tsx +2 -0
  560. package/src/modules/sales/api/documents/factory.ts +13 -1
  561. package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +6 -0
  562. package/src/modules/sales/backend/sales/channels/offers/page.tsx +10 -4
  563. package/src/modules/sales/backend/sales/channels/page.tsx +19 -4
  564. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +73 -20
  565. package/src/modules/sales/backend/sales/documents/create/page.tsx +2 -0
  566. package/src/modules/sales/commands/documentAddresses.ts +226 -4
  567. package/src/modules/sales/commands/documents.ts +28 -0
  568. package/src/modules/sales/commands/returns.ts +12 -3
  569. package/src/modules/sales/commands/shared.ts +36 -0
  570. package/src/modules/sales/commands/shipments.ts +17 -1
  571. package/src/modules/sales/components/AdjustmentKindSettings.tsx +20 -11
  572. package/src/modules/sales/components/DocumentNumberSettings.tsx +1 -0
  573. package/src/modules/sales/components/OrderEditingSettings.tsx +1 -0
  574. package/src/modules/sales/components/PaymentMethodsSettings.tsx +12 -4
  575. package/src/modules/sales/components/ShippingMethodsSettings.tsx +12 -4
  576. package/src/modules/sales/components/StatusSettings.tsx +20 -11
  577. package/src/modules/sales/components/TaxRatesSettings.tsx +12 -5
  578. package/src/modules/sales/components/channels/ChannelOfferForm.tsx +67 -14
  579. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +7 -4
  580. package/src/modules/sales/components/documents/AddressesSection.tsx +35 -25
  581. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +50 -25
  582. package/src/modules/sales/components/documents/ItemsSection.tsx +24 -13
  583. package/src/modules/sales/components/documents/LineItemDialog.tsx +26 -9
  584. package/src/modules/sales/components/documents/PaymentDialog.tsx +33 -14
  585. package/src/modules/sales/components/documents/PaymentsSection.tsx +22 -10
  586. package/src/modules/sales/components/documents/ReturnDialog.tsx +28 -17
  587. package/src/modules/sales/components/documents/ReturnsSection.tsx +4 -1
  588. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +11 -4
  589. package/src/modules/sales/components/documents/ShipmentDialog.tsx +23 -8
  590. package/src/modules/sales/components/documents/ShipmentsSection.tsx +20 -10
  591. package/src/modules/sales/components/documents/optimisticLock.ts +34 -0
  592. package/src/modules/sales/components/documents/shipmentTypes.ts +1 -0
  593. package/src/modules/sales/di.ts +35 -0
  594. package/src/modules/sales/i18n/de.json +3 -0
  595. package/src/modules/sales/i18n/en.json +3 -0
  596. package/src/modules/sales/i18n/es.json +3 -0
  597. package/src/modules/sales/i18n/pl.json +3 -0
  598. package/src/modules/staff/api/job-histories.ts +12 -2
  599. package/src/modules/staff/api/timesheets/time-entries/route.ts +16 -4
  600. package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +12 -7
  601. package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +2 -0
  602. package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +16 -5
  603. package/src/modules/staff/backend/staff/team-members/page.tsx +6 -2
  604. package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +8 -0
  605. package/src/modules/staff/backend/staff/team-roles/page.tsx +6 -2
  606. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +13 -3
  607. package/src/modules/staff/backend/staff/teams/page.tsx +9 -3
  608. package/src/modules/staff/backend/staff/timesheets/page.tsx +10 -1
  609. package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +4 -0
  610. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +9 -3
  611. package/src/modules/staff/commands/job-histories.ts +42 -3
  612. package/src/modules/staff/components/LeaveRequestForm.tsx +2 -0
  613. package/src/modules/staff/components/TeamForm.tsx +2 -0
  614. package/src/modules/staff/components/TeamMemberForm.tsx +2 -0
  615. package/src/modules/staff/components/TeamRoleForm.tsx +2 -0
  616. package/src/modules/staff/components/detail/JobHistorySection.tsx +28 -6
  617. package/src/modules/staff/data/validators.ts +6 -0
  618. package/src/modules/staff/i18n/de.json +1 -0
  619. package/src/modules/staff/i18n/en.json +1 -0
  620. package/src/modules/staff/i18n/es.json +1 -0
  621. package/src/modules/staff/i18n/pl.json +1 -0
  622. package/src/modules/staff/lib/leaveRequestHelpers.ts +4 -0
  623. package/src/modules/translations/components/TranslationManager.tsx +13 -8
  624. package/src/modules/workflows/api/definitions/[id]/route.ts +112 -0
  625. package/src/modules/workflows/backend/definitions/[id]/page.tsx +20 -4
  626. package/src/modules/workflows/backend/definitions/page.tsx +20 -9
  627. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +29 -16
  628. package/src/modules/workflows/components/formConfig.tsx +5 -0
  629. package/src/modules/workflows/di.ts +20 -0
  630. package/src/modules/workflows/i18n/de.json +1 -0
  631. package/src/modules/workflows/i18n/en.json +1 -0
  632. package/src/modules/workflows/i18n/es.json +1 -0
  633. package/src/modules/workflows/i18n/pl.json +1 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/sales/components/channels/ChannelOfferForm.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm, type CrudField, type CrudFormGroup, type CrudFormGroupComponentProps } from '@open-mercato/ui/backend/CrudForm'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { createCrud, updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError, type CrudServerFieldErrors } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { readApiResultOrThrow, apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Loader2, Search, Image as ImageIcon, Trash2 } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { E } from '#generated/entities.ids.generated'\nimport { buildAttachmentImageUrl, slugifyAttachmentFileName } from '@open-mercato/core/modules/attachments/lib/imageUrls'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\ntype PriceKindSummary = {\n id: string\n code: string | null\n title: string | null\n displayMode: 'including-tax' | 'excluding-tax'\n currencyCode: string | null\n}\n\ntype PriceOverrideDraft = {\n tempId: string\n priceId?: string | null\n priceKindId?: string | null\n priceKindCode?: string | null\n currencyCode?: string | null\n displayMode?: 'including-tax' | 'excluding-tax' | null\n amount?: string\n}\n\nexport type OfferFormValues = {\n channelId: string | null\n productId: string | null\n title: string\n description: string\n defaultMediaId?: string | null\n isActive: boolean\n priceOverrides: PriceOverrideDraft[]\n} & Record<string, unknown>\n\ntype ChannelOfferFormProps = {\n channelId?: string\n offerId?: string\n mode: 'create' | 'edit'\n}\n\ntype OfferResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype PriceResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype AttachmentsResponse = {\n items?: Array<{ id?: string; fileName?: string; url?: string; thumbnailUrl?: string | null }>\n}\n\ntype ProductSummaryCacheEntry = {\n title: string\n description: string | null\n defaultMediaId: string | null\n defaultMediaUrl: string | null\n sku: string | null\n pricing: PricingSummary | null\n}\n\ntype MediaOption = { id: string; label: string; fileName: string; thumbnailUrl?: string | null }\n\ntype PricingSummary = {\n currencyCode: string | null\n unitPriceNet: string | null\n unitPriceGross: string | null\n displayMode: 'including-tax' | 'excluding-tax' | null\n}\n\ntype ProductVariantPreview = {\n id: string\n name: string\n sku: string | null\n thumbnailUrl: string | null\n thumbnailId: string | null\n thumbnailFileName: string | null\n}\n\ntype ProductSummary = ProductSummaryCacheEntry | null\n\ntype ProductSearchResult = {\n id: string\n title: string\n sku: string | null\n defaultMediaUrl: string | null\n pricing: PricingSummary | null\n existingOfferId: string | null\n existingOfferTitle: string | null\n isCurrentOfferProduct: boolean\n}\n\nconst UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/\nconst MAX_LIST_PAGE_SIZE = 100\ntype VariantThumbnailInfo = { attachmentId: string | null; thumbnailUrl: string | null; fileName: string | null }\n\nexport function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }: ChannelOfferFormProps) {\n const t = useT()\n const router = useRouter()\n const [initialValues, setInitialValues] = React.useState<OfferFormValues | null>(mode === 'create'\n ? {\n channelId: lockedChannelId ?? null,\n productId: null,\n title: '',\n description: '',\n defaultMediaId: null,\n isActive: true,\n priceOverrides: [],\n }\n : null)\n const [loading, setLoading] = React.useState(mode === 'edit')\n const [error, setError] = React.useState<string | null>(null)\n const [priceKinds, setPriceKinds] = React.useState<PriceKindSummary[]>([])\n const [mediaOptions, setMediaOptions] = React.useState<MediaOption[]>([])\n const attachmentCache = React.useRef<Map<string, MediaOption[]>>(new Map())\n const productCache = React.useRef<Map<string, ProductSummaryCacheEntry>>(new Map())\n const [productSummary, setProductSummary] = React.useState<ProductSummary>(null)\n const [variantPreviews, setVariantPreviews] = React.useState<ProductVariantPreview[]>([])\n const variantCache = React.useRef<Map<string, ProductVariantPreview[]>>(new Map())\n const variantMediaCache = React.useRef<Map<string, VariantThumbnailInfo>>(new Map())\n const [selectedChannelId, setSelectedChannelId] = React.useState<string | null>(lockedChannelId ?? null)\n const manualMediaSelections = React.useRef<Set<string>>(new Set())\n const initialPriceIdsRef = React.useRef<Set<string>>(new Set())\n const [currentProductId, setCurrentProductId] = React.useState<string | null>(null)\n React.useEffect(() => {\n if (initialValues) {\n initialPriceIdsRef.current = collectPriceIds(initialValues.priceOverrides)\n } else {\n initialPriceIdsRef.current = new Set()\n }\n }, [initialValues])\n const channelOffersHref = React.useMemo(\n () => buildChannelOffersHref(lockedChannelId),\n [lockedChannelId],\n )\n\n React.useEffect(() => {\n if (lockedChannelId) {\n setSelectedChannelId(lockedChannelId)\n } else if (initialValues?.channelId) {\n setSelectedChannelId(initialValues.channelId)\n }\n }, [initialValues?.channelId, lockedChannelId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string') {\n setCurrentProductId(initialValues.productId)\n }\n }, [initialValues?.productId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string' && initialValues?.defaultMediaId === null) {\n manualMediaSelections.current.add(initialValues.productId)\n }\n }, [initialValues?.defaultMediaId, initialValues?.productId])\n\n React.useEffect(() => {\n if (mode !== 'edit') return\n const productId = typeof initialValues?.productId === 'string' ? initialValues.productId : null\n if (!productId) return\n const resolvedProductId = productId\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof initialValues?.channelId === 'string' ? initialValues.channelId : null)\n let cancelled = false\n async function hydrateExistingProduct() {\n try {\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n resolveProductMediaOptionsWithCache({ productId: resolvedProductId, attachmentCache }),\n resolveVariantPreviewsWithCache({ productId: resolvedProductId, variantCache, variantMediaCache }),\n ])\n if (!cancelled) {\n setProductSummary(summary ?? null)\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.initialHydrate', err)\n }\n }\n void hydrateExistingProduct()\n return () => {\n cancelled = true\n }\n }, [\n attachmentCache,\n initialValues?.channelId,\n initialValues?.productId,\n lockedChannelId,\n mode,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n ])\n\n React.useEffect(() => {\n async function loadKinds() {\n const mapItems = (items: Array<Record<string, unknown>>): PriceKindSummary[] =>\n items.map((item): PriceKindSummary => {\n const displayMode =\n item.displayMode === 'including-tax' || item.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax'\n return {\n id: typeof item.id === 'string' ? item.id : '',\n code: typeof item.code === 'string' ? item.code : null,\n title: typeof item.title === 'string' ? item.title : null,\n currencyCode:\n typeof item.currencyCode === 'string'\n ? item.currencyCode\n : typeof item.currency_code === 'string'\n ? item.currency_code\n : null,\n displayMode,\n }\n })\n const endpoints = [\n `/api/sales/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n `/api/catalog/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n ]\n try {\n for (const endpoint of endpoints) {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n endpoint,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setPriceKinds(mapItems(items))\n return\n } catch (err) {\n console.error('sales.channels.price-kinds.fetch', { endpoint, err })\n }\n }\n setPriceKinds([])\n } catch (err) {\n console.error('catalog.price-kinds.list', err)\n }\n }\n void loadKinds()\n }, [])\n\n React.useEffect(() => {\n if (mode !== 'edit' || !offerId) return\n const offerKey = offerId\n let cancelled = false\n async function loadOffer() {\n setLoading(true)\n setError(null)\n try {\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/offers?id=${encodeURIComponent(offerKey)}&pageSize=1`,\n undefined,\n { errorMessage: t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.') },\n )\n const offer = Array.isArray(payload.items) ? payload.items[0] : null\n if (!offer) throw new Error(t('sales.channels.offers.errors.notFound', 'Offer not found.'))\n const values = mapOfferToFormValues(offer, lockedChannelId)\n const pricePayload = await readApiResultOrThrow<PriceResponse>(\n `/api/catalog/prices?offerId=${encodeURIComponent(offer.id as string)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const priceItems = Array.isArray(pricePayload.items) ? pricePayload.items : []\n values.priceOverrides = priceItems.map(mapPriceRow)\n let preloadedMedia: MediaOption[] = []\n let preloadedVariants: ProductVariantPreview[] = []\n let preloadedSummary: ProductSummary | null = null\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (productId) {\n try {\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof values.channelId === 'string' ? values.channelId : null)\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n loadProductMedia(productId),\n resolveVariantPreviewsWithCache({ productId, variantCache, variantMediaCache }),\n ])\n preloadedSummary = summary ?? null\n preloadedVariants = variants\n preloadedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(productId, preloadedMedia)\n } catch (err) {\n console.error('sales.channels.offer.media.preload', err)\n }\n }\n if (!cancelled) {\n setInitialValues(values)\n setProductSummary(preloadedSummary)\n setVariantPreviews(preloadedVariants)\n setMediaOptions(preloadedMedia)\n }\n } catch (err) {\n console.error('sales.channels.offer.load', err)\n if (!cancelled) setError(t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.'))\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadOffer()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n lockedChannelId,\n mode,\n offerId,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n t,\n variantCache,\n variantMediaCache,\n ])\n\n const fields = React.useMemo<CrudField[]>(() => [\n {\n id: 'channelId',\n label: t('sales.channels.offers.form.channel', 'Channel'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ChannelSelectInput\n value={(value as string | null) ?? lockedChannelId ?? null}\n onChange={(next) => {\n setValue(next ?? null)\n setSelectedChannelId(next ?? null)\n }}\n disabled={!!lockedChannelId}\n showDetailsLink\n />\n ),\n },\n {\n id: 'productId',\n label: t('sales.channels.offers.form.product', 'Product'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ProductSelectInput\n value={(value as string | null) ?? null}\n onChange={(next) => setValue(next)}\n channelId={selectedChannelId}\n currentOfferId={offerId ?? null}\n />\n ),\n },\n {\n id: 'defaultMediaId',\n label: t('sales.channels.offers.form.defaultMedia', 'Default media'),\n type: 'custom',\n component: ({ value, setValue }) => (\n <DefaultMediaSelect\n value={(value as string | null | undefined) ?? null}\n onChange={(next) => {\n setValue(next)\n if (!currentProductId) return\n if (next === null || next === undefined) {\n manualMediaSelections.current.add(currentProductId)\n } else {\n manualMediaSelections.current.delete(currentProductId)\n }\n }}\n options={mediaOptions}\n productThumbnail={productSummary?.defaultMediaUrl ?? null}\n hasProduct={Boolean(productSummary)}\n productDefaultMediaId={productSummary?.defaultMediaId ?? null}\n />\n ),\n },\n {\n id: 'title',\n label: t('sales.channels.offers.form.title', 'Title'),\n type: 'text',\n required: true,\n },\n {\n id: 'description',\n label: t('sales.channels.offers.form.description', 'Description'),\n type: 'textarea',\n },\n {\n id: 'isActive',\n label: t('sales.channels.offers.form.active', 'Active'),\n type: 'checkbox',\n },\n ], [lockedChannelId, mediaOptions, productSummary, selectedChannelId, t, currentProductId])\n\n const handleOverrideRemove = React.useCallback(async (draft: PriceOverrideDraft) => {\n const priceId = typeof draft?.priceId === 'string' ? draft.priceId : null\n if (!priceId) return true\n if (mode !== 'edit') return true\n try {\n await deleteCrud('catalog/prices', priceId, {\n errorMessage: t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'),\n })\n initialPriceIdsRef.current.delete(priceId)\n return true\n } catch (err) {\n console.error('sales.channels.pricing.remove', err)\n flash(t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'), 'error')\n return false\n }\n }, [mode, t])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => [\n { id: 'associations', column: 1, title: t('sales.channels.offers.form.groups.associations', 'Associations'), fields: ['channelId'] },\n {\n id: 'product',\n column: 1,\n title: t('sales.channels.offers.form.productGroup', 'Product'),\n description: t('sales.channels.offers.form.productGroupHelp', 'Search the catalog and pick the product you want to customize for this channel.'),\n fields: ['productId'],\n },\n {\n id: 'productSummary',\n column: 2,\n title: t('sales.channels.offers.form.productSummaryTitle', 'Product summary'),\n component: () => (\n <ProductOverviewCard summary={productSummary} variants={variantPreviews} />\n ),\n },\n {\n id: 'media',\n column: 1,\n title: t('sales.channels.offers.form.mediaGroupTitle', 'Default media override'),\n fields: ['defaultMediaId'],\n },\n { id: 'content', column: 1, title: t('sales.channels.offers.form.groups.content', 'Content'), fields: ['title', 'description', 'isActive'] },\n {\n id: 'pricing',\n column: 1,\n title: t('sales.channels.offers.form.groups.pricing', 'Price overrides'),\n component: ({ values, setValue }) => (\n <PriceOverridesEditor\n values={Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []}\n onChange={(next) => setValue('priceOverrides', next)}\n priceKinds={priceKinds}\n basePrice={productSummary?.pricing ?? null}\n onRemoveDraft={handleOverrideRemove}\n />\n ),\n },\n {\n id: 'customFields',\n column: 2,\n title: t('entities.customFields.title', 'Custom attributes'),\n kind: 'customFields',\n },\n {\n id: 'watchers',\n column: 1,\n bare: true,\n component: ({ values, setValue, errors }) => (\n <OfferFormWatchers\n values={values}\n setValue={setValue}\n errors={errors}\n productCache={productCache}\n attachmentCache={attachmentCache}\n setMediaOptions={setMediaOptions}\n setProductSummary={setProductSummary}\n setVariantPreviews={setVariantPreviews}\n variantCache={variantCache}\n variantMediaCache={variantMediaCache}\n channelId={selectedChannelId}\n manualMediaSelections={manualMediaSelections}\n setCurrentProductId={setCurrentProductId}\n />\n ),\n },\n ], [\n attachmentCache,\n handleOverrideRemove,\n manualMediaSelections,\n priceKinds,\n productCache,\n productSummary,\n selectedChannelId,\n setMediaOptions,\n setCurrentProductId,\n t,\n variantPreviews,\n ])\n\n const handleSubmit = React.useCallback(async (values: OfferFormValues) => {\n const channelId = typeof values.channelId === 'string' && values.channelId.length\n ? values.channelId\n : selectedChannelId ?? lockedChannelId\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (!channelId || !productId) {\n throw new Error(t('sales.channels.offers.errors.requiredFields', 'Choose a channel and product.'))\n }\n const resolvedDefaultMediaId = typeof values.defaultMediaId === 'string' && values.defaultMediaId.trim().length\n ? values.defaultMediaId\n : values.defaultMediaId === null\n ? null\n : undefined\n const basePayload: Record<string, unknown> = {\n channelId,\n productId,\n title: values.title?.trim() || undefined,\n description: values.description?.trim() || undefined,\n isActive: values.isActive !== false,\n }\n if (resolvedDefaultMediaId !== undefined) {\n basePayload.defaultMediaId = resolvedDefaultMediaId\n }\n const attachmentLookup = attachmentCache.current.get(productId) ?? []\n const mediaMap = new Map(attachmentLookup.map((entry) => [entry.id, entry.fileName]))\n if (typeof resolvedDefaultMediaId === 'string' && mediaMap.has(resolvedDefaultMediaId)) {\n const fileName = mediaMap.get(resolvedDefaultMediaId) ?? null\n basePayload.defaultMediaUrl = buildAttachmentImageUrl(resolvedDefaultMediaId, {\n slug: slugifyAttachmentFileName(fileName),\n })\n } else if (resolvedDefaultMediaId === null) {\n basePayload.defaultMediaUrl = null\n }\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) basePayload.customFields = customFields\n const overrides = Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []\n const priceWithoutKind = overrides.find((entry) => {\n const amount = typeof entry.amount === 'string' ? entry.amount.trim() : entry.amount\n const hasAmount = typeof amount === 'string' ? amount.length > 0 : amount !== undefined && amount !== null\n const hasExistingPrice = typeof entry.priceId === 'string' && entry.priceId.length > 0\n const hasCurrency = typeof entry.currencyCode === 'string' && entry.currencyCode.length > 0\n return !entry.priceKindId && (hasAmount || hasExistingPrice || hasCurrency)\n })\n if (priceWithoutKind) {\n throw createCrudFormError(t('sales.channels.offers.errors.priceKindRequired', 'Select a price kind for each override.'), {})\n }\n const duplicateKind = (() => {\n const seen = new Set<string>()\n for (const entry of overrides) {\n const kindId = typeof entry.priceKindId === 'string' ? entry.priceKindId : null\n if (!kindId) continue\n if (seen.has(kindId)) return kindId\n seen.add(kindId)\n }\n return null\n })()\n if (duplicateKind) {\n throw createCrudFormError(\n t('sales.channels.offers.errors.priceKindDuplicate', 'Each price kind can only be overridden once.'),\n {},\n )\n }\n const submittedPriceIds = collectPriceIds(overrides)\n const deletedIdSet = new Set<string>()\n initialPriceIdsRef.current.forEach((id) => {\n if (!submittedPriceIds.has(id)) deletedIdSet.add(id)\n })\n const deletedIds = Array.from(deletedIdSet)\n let savedId = offerId ?? null\n try {\n if (mode === 'create') {\n const res = await createCrud<{ id?: string; offerId?: string }>('catalog/offers', basePayload, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = res?.result?.offerId ?? res?.result?.id ?? null\n } else if (offerId) {\n await updateCrud('catalog/offers', { id: offerId, ...basePayload }, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = offerId\n }\n } catch (err) {\n const details = (err as { details?: unknown })?.details\n const rawFieldErrors = (err as { fieldErrors?: unknown })?.fieldErrors\n const fieldErrors = rawFieldErrors && typeof rawFieldErrors === 'object'\n ? (rawFieldErrors as CrudServerFieldErrors)\n : undefined\n const status = (err as { status?: number })?.status\n const message = typeof (err as { message?: unknown }).message === 'string' && (err as { message: string }).message.trim().length\n ? (err as { message: string }).message\n : t(\n 'sales.channels.offers.errors.duplicateProduct',\n 'This product already has an offer in this channel.',\n )\n throw createCrudFormError(\n message,\n fieldErrors,\n { status, details },\n )\n }\n if (savedId) {\n await syncPriceOverrides({\n overrides,\n deletedIds,\n offerId: savedId,\n channelId,\n productId,\n })\n initialPriceIdsRef.current = submittedPriceIds\n }\n flash(t('sales.channels.offers.messages.saved', 'Offer saved.'), 'success')\n router.push(buildChannelOffersHref(channelId))\n }, [attachmentCache, initialPriceIdsRef, lockedChannelId, mode, offerId, router, selectedChannelId, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!offerId) return\n await deleteCrud('catalog/offers', offerId, {\n errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),\n })\n flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')\n const targetChannel = initialValues?.channelId ?? lockedChannelId ?? ''\n router.push(buildChannelOffersHref(targetChannel))\n }, [initialValues?.channelId, lockedChannelId, offerId, router, t])\n\n return (\n <div>\n {error ? (\n <div className=\"mb-4 rounded border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive\">\n {error}\n </div>\n ) : null}\n <CrudForm<OfferFormValues>\n title={mode === 'create'\n ? t('sales.channels.offers.form.createTitle', 'Create offer')\n : t('sales.channels.offers.form.editTitle', 'Edit offer')}\n entityId={E.catalog.catalog_offer}\n fields={fields}\n groups={groups}\n initialValues={initialValues ?? undefined}\n isLoading={loading}\n loadingMessage={t('sales.channels.offers.form.loading', 'Loading offer\u2026')}\n submitLabel={mode === 'create'\n ? t('sales.channels.offers.form.createSubmit', 'Create offer')\n : t('sales.channels.offers.form.updateSubmit', 'Save changes')}\n cancelHref={channelOffersHref}\n backHref={channelOffersHref}\n onSubmit={handleSubmit}\n onDelete={mode === 'edit' ? handleDelete : undefined}\n deleteVisible={mode === 'edit'}\n deleteRedirect={channelOffersHref}\n />\n </div>\n )\n}\n\nfunction mapOfferToFormValues(item: Record<string, unknown>, lockedChannelId?: string | null): OfferFormValues {\n const values: OfferFormValues = {\n channelId: typeof item.channelId === 'string'\n ? item.channelId\n : typeof item.channel_id === 'string'\n ? item.channel_id\n : lockedChannelId ?? null,\n productId: typeof item.productId === 'string'\n ? item.productId\n : typeof item.product_id === 'string'\n ? item.product_id\n : null,\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : '',\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n isActive: item.isActive === true || item.is_active === true,\n priceOverrides: [],\n }\n mergeCustomFieldValues(values, item)\n return values\n}\n\nfunction mapPriceRow(row: Record<string, unknown>): PriceOverrideDraft {\n return {\n tempId: String(row.id ?? crypto.randomUUID?.() ?? Math.random()),\n priceId: typeof row.id === 'string' ? row.id : undefined,\n priceKindId: typeof row.priceKindId === 'string'\n ? row.priceKindId\n : typeof row.price_kind_id === 'string'\n ? row.price_kind_id\n : undefined,\n priceKindCode: typeof row.priceKindCode === 'string'\n ? row.priceKindCode\n : typeof row.price_kind_code === 'string'\n ? row.price_kind_code\n : null,\n currencyCode: typeof row.currencyCode === 'string'\n ? row.currencyCode\n : typeof row.currency_code === 'string'\n ? row.currency_code\n : null,\n displayMode: row.displayMode === 'including-tax' || row.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax',\n amount: typeof row.unitPriceNet === 'string'\n ? row.unitPriceNet\n : typeof row.unit_price_net === 'string'\n ? row.unit_price_net\n : typeof row.unitPriceGross === 'string'\n ? row.unitPriceGross\n : typeof row.unit_price_gross === 'string'\n ? row.unit_price_gross\n : '',\n }\n}\n\nfunction collectPriceIds(source: PriceOverrideDraft[] | null | undefined): Set<string> {\n if (!Array.isArray(source)) return new Set()\n const ids = source\n .map((entry) => (typeof entry?.priceId === 'string' ? entry.priceId : null))\n .filter((id): id is string => Boolean(id))\n return new Set(ids)\n}\n\nfunction mergeCustomFieldValues(target: Record<string, unknown>, source: Record<string, unknown> | null | undefined) {\n Object.assign(target, extractCustomFieldEntries(source ?? {}))\n}\n\nfunction buildChannelOffersHref(channelId?: string | null): string {\n return channelId && channelId.length\n ? `/backend/sales/channels/${channelId}/edit?tab=offers`\n : '/backend/sales/channels/offers'\n}\n\nasync function syncPriceOverrides(params: {\n overrides: PriceOverrideDraft[]\n deletedIds: string[]\n offerId: string\n channelId: string\n productId: string\n}) {\n const { overrides, deletedIds, offerId, channelId, productId } = params\n for (const draft of overrides) {\n if (!draft.priceKindId || !draft.amount) continue\n const amount = Number(draft.amount)\n if (Number.isNaN(amount)) continue\n const payload: Record<string, unknown> = {\n offerId,\n productId,\n channelId,\n priceKindId: draft.priceKindId,\n currencyCode: draft.currencyCode ?? undefined,\n }\n if (draft.displayMode === 'including-tax') {\n payload.unitPriceGross = amount\n } else {\n payload.unitPriceNet = amount\n }\n if (draft.priceId) {\n await updateCrud('catalog/prices', { id: draft.priceId, ...payload })\n } else {\n await createCrud('catalog/prices', payload)\n }\n }\n const uniqueDeletedIds = Array.from(new Set(\n deletedIds.filter((id): id is string => typeof id === 'string' && id.length > 0),\n ))\n for (const id of uniqueDeletedIds) {\n if (!id) continue\n try {\n await deleteCrud('catalog/prices', id)\n } catch (err) {\n console.error('catalog.prices.delete', err)\n }\n }\n}\n\nfunction ChannelSelectInput({\n value,\n onChange,\n disabled,\n showDetailsLink,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n disabled?: boolean\n showDetailsLink?: boolean\n}) {\n const t = useT()\n const [options, setOptions] = React.useState<Array<{ id: string; name: string; code: string | null }>>([])\n const selectedOption = React.useMemo(\n () => (value ? options.find((opt) => opt.id === value) ?? null : null),\n [options, value],\n )\n React.useEffect(() => {\n async function load() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setOptions(items.map((item) => ({\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string' ? item.name : '',\n code: typeof item.code === 'string' ? item.code : null,\n })))\n } catch (err) {\n console.error('sales.channels.options', err)\n }\n }\n void load()\n }, [])\n React.useEffect(() => {\n const channelIdToLoad = typeof value === 'string' ? value : null\n if (!channelIdToLoad || selectedOption) return\n const resolvedChannelId = channelIdToLoad\n let cancelled = false\n async function loadSingle() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?id=${encodeURIComponent(resolvedChannelId)}&pageSize=1`,\n undefined,\n { fallback: { items: [] } },\n )\n const item = Array.isArray(payload.items) ? payload.items[0] : null\n if (!item || cancelled) return\n const entry = {\n id: typeof item.id === 'string' ? item.id : resolvedChannelId,\n name: typeof item.name === 'string' ? item.name : resolvedChannelId,\n code: typeof item.code === 'string' ? item.code : null,\n }\n setOptions((prev) => {\n if (prev.some((opt) => opt.id === entry.id)) return prev\n return [...prev, entry]\n })\n } catch (err) {\n console.error('sales.channels.lookup', err)\n }\n }\n void loadSingle()\n return () => { cancelled = true }\n }, [selectedOption, value])\n\n if (disabled && value) {\n const label = selectedOption?.name ?? value\n const detail = selectedOption?.code ?? null\n return (\n <div className=\"flex items-center justify-between gap-3 rounded border bg-muted px-3 py-2 text-sm\">\n <div className=\"min-w-0\">\n <div className=\"font-medium truncate\">{label}</div>\n {detail ? (\n <div className=\"text-xs text-muted-foreground truncate\">{detail}</div>\n ) : null}\n </div>\n {showDetailsLink ? (\n <Link href={`/backend/sales/channels/${value}/edit`} className=\"text-xs font-medium text-primary hover:underline\">\n {t('sales.channels.offers.form.channelDetails', 'Details')}\n </Link>\n ) : null}\n </div>\n )\n }\n return (\n <Select value={value || undefined} onValueChange={(next) => onChange(next || null)}>\n <SelectTrigger>\n <SelectValue placeholder={t('sales.channels.offers.form.channelPlaceholder', 'Select channel')} />\n </SelectTrigger>\n <SelectContent>\n {options.map((opt) => (\n <SelectItem key={opt.id} value={opt.id}>\n {opt.code ? `${opt.name} (${opt.code})` : opt.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\nfunction ProductSelectInput({\n value,\n onChange,\n channelId,\n currentOfferId,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n channelId: string | null\n currentOfferId?: string | null\n}) {\n const t = useT()\n const [query, setQuery] = React.useState('')\n const [results, setResults] = React.useState<ProductSearchResult[]>([])\n const [isLoading, setLoading] = React.useState(false)\n const [hasTyped, setHasTyped] = React.useState(false)\n\n const trimmed = query.trim()\n const shouldSearch = trimmed.length >= 2 || UUID_REGEX.test(trimmed)\n\n React.useEffect(() => {\n if (!shouldSearch) {\n setResults([])\n return\n }\n let cancelled = false\n const controller = new AbortController()\n const timeout = setTimeout(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({ pageSize: '10' })\n if (UUID_REGEX.test(trimmed)) {\n params.set('id', trimmed)\n } else if (trimmed.length) {\n params.set('search', trimmed)\n }\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/products?${params.toString()}`,\n { signal: controller.signal },\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n if (!cancelled) {\n const mapped = items.map((item) => mapProductSearchResult(item, channelId, currentOfferId))\n mapped.sort((a, b) => {\n const aBlocked = Boolean(a.existingOfferId && !a.isCurrentOfferProduct)\n const bBlocked = Boolean(b.existingOfferId && !b.isCurrentOfferProduct)\n return Number(aBlocked) - Number(bBlocked)\n })\n setResults(mapped)\n }\n } catch (err) {\n if ((err as Error).name === 'AbortError') return\n console.error('catalog.products.lookup', err)\n } finally {\n if (!cancelled) setLoading(false)\n }\n }, 250)\n return () => {\n cancelled = true\n clearTimeout(timeout)\n controller.abort()\n }\n }, [channelId, currentOfferId, shouldSearch, trimmed])\n\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter' && UUID_REGEX.test(trimmed)) {\n event.preventDefault()\n onChange(trimmed)\n }\n }, [onChange, trimmed])\n\n const selectedHint = value\n ? t('sales.channels.offers.form.productSelectedHint', 'Selected product ID: {{id}}', { id: value })\n : null\n\n return (\n <div className=\"space-y-3\">\n <Input\n leftIcon={<Search />}\n value={query}\n onChange={(event) => {\n setQuery(event.target.value)\n setHasTyped(true)\n }}\n onKeyDown={handleKeyDown}\n placeholder={t('sales.channels.offers.form.productSearchPlaceholder', 'Search by title, SKU, or ID\u2026')}\n />\n {selectedHint ? (\n <div className=\"rounded border bg-muted px-3 py-2 text-xs text-muted-foreground\">\n {selectedHint}\n </div>\n ) : null}\n {value ? (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => onChange(null)}>\n {t('sales.channels.offers.form.productClear', 'Clear selection')}\n </Button>\n ) : null}\n {shouldSearch ? (\n <div className=\"space-y-2\">\n {isLoading ? (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n {t('sales.channels.offers.form.productSearchLoading', 'Searching products\u2026')}\n </div>\n ) : null}\n {!isLoading && !results.length ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchEmpty', 'No products match your search.')}\n </p>\n ) : null}\n <div className=\"space-y-2 max-h-80 overflow-y-auto\">\n {results.map((product) => {\n const isSelected = value === product.id\n const hasConflict = Boolean(product.existingOfferId && !product.isCurrentOfferProduct)\n return (\n <div\n key={product.id}\n className={cn(\n 'flex gap-3 rounded border bg-card p-3 transition-colors',\n isSelected ? 'border-primary/70 bg-primary/5' : 'hover:border-primary/50',\n )}\n >\n <div className=\"h-12 w-12 overflow-hidden rounded border bg-muted\">\n {product.defaultMediaUrl ? (\n <img src={product.defaultMediaUrl} alt={product.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex flex-1 flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium\">{product.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {product.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {product.sku}</div>\n ) : null}\n </div>\n <div className=\"text-xs font-medium text-muted-foreground\">\n {product.pricing ? formatPriceDisplay(product.pricing) : t('sales.channels.offers.form.productPriceMissing', 'No price')}\n </div>\n </div>\n {hasConflict ? (\n <div className=\"flex items-center justify-between gap-2 text-xs text-status-warning-text\">\n <span className=\"truncate\">\n {t('sales.channels.offers.form.productHasOffer', 'Already has an offer for this channel.')}\n </span>\n {channelId && product.existingOfferId ? (\n <Link\n href={`/backend/sales/channels/${encodeURIComponent(\n String(channelId)\n )}/offers/${encodeURIComponent(String(product.existingOfferId))}/edit`}\n className=\"shrink-0 font-medium text-primary hover:underline\"\n >\n {t('sales.channels.offers.form.productHasOfferLink', 'View offer')}\n </Link>\n ) : null}\n </div>\n ) : null}\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant={isSelected ? 'secondary' : 'outline'}\n size=\"sm\"\n onClick={() => onChange(product.id)}\n disabled={hasConflict && !isSelected}\n >\n {hasConflict && !isSelected\n ? t('sales.channels.offers.form.productUnavailable', 'Unavailable')\n : isSelected\n ? t('sales.channels.offers.form.productSelected', 'Selected')\n : t('sales.channels.offers.form.productSelect', 'Select')}\n </Button>\n </div>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : hasTyped ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchHint', 'Type at least 2 characters or paste a product ID.')}\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchIntro', 'Search by name or paste the product id to find catalog items.')}\n </p>\n )}\n </div>\n )\n}\n\nfunction DefaultMediaSelect({\n value,\n options,\n onChange,\n productThumbnail,\n hasProduct,\n productDefaultMediaId,\n}: {\n value: string | null\n options: MediaOption[]\n onChange: (next: string | null) => void\n productThumbnail: string | null\n hasProduct: boolean\n productDefaultMediaId?: string | null\n}) {\n const t = useT()\n const filteredOptions = React.useMemo(() => {\n if (!productDefaultMediaId) return options\n return options.filter((opt) => opt.id !== productDefaultMediaId)\n }, [options, productDefaultMediaId])\n const hasAttachmentOptions = filteredOptions.length > 0\n const showPlaceholder = !hasAttachmentOptions && !productThumbnail && !hasProduct\n if (showPlaceholder) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.mediaSelectProduct', 'Select a product to load its media.')}\n </p>\n )\n }\n const tiles = [\n {\n id: 'inherit',\n label: t('sales.channels.offers.form.mediaInherit', 'Use product default'),\n thumbnail: productThumbnail,\n selected: value == null,\n onClick: () => onChange(null),\n },\n ...filteredOptions.map((opt) => ({\n id: opt.id,\n label: opt.label,\n thumbnail: opt.thumbnailUrl ?? null,\n selected: value === opt.id,\n onClick: () => onChange(opt.id),\n })),\n ]\n return (\n <div className=\"space-y-3\">\n <div className=\"text-xs text-muted-foreground\">\n <p>\n {t('sales.channels.offers.form.mediaHelp', 'Choose the thumbnail that should represent this offer in the channel.')}\n </p>\n {!hasAttachmentOptions && hasProduct ? (\n <p className=\"mt-1\">\n {t('sales.channels.offers.form.mediaEmpty', 'This product has no uploaded media yet; the product default will be used.')}\n </p>\n ) : null}\n </div>\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {tiles.map((tile) => (\n <button\n key={tile.id}\n type=\"button\"\n className={cn(\n 'flex flex-col rounded border text-left transition-colors',\n tile.selected ? 'border-primary shadow-sm' : 'hover:border-primary/60',\n )}\n onClick={tile.onClick}\n >\n <div className=\"relative aspect-square overflow-hidden rounded-t bg-muted\">\n {tile.thumbnail ? (\n <img src={tile.thumbnail} alt={tile.label} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-6 w-6\" />\n </div>\n )}\n {tile.selected ? (\n <div className=\"absolute right-2 top-2 rounded-full bg-primary/90 px-2 py-0.5 text-xs font-semibold text-primary-foreground\">\n {t('sales.channels.offers.form.mediaSelected', 'Active')}\n </div>\n ) : null}\n </div>\n <div className=\"p-2\">\n <div className=\"line-clamp-2 text-xs font-medium\">{tile.label}</div>\n </div>\n </button>\n ))}\n </div>\n </div>\n )\n}\n\nfunction OfferFormWatchers({\n values,\n setValue,\n productCache,\n attachmentCache,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n channelId,\n manualMediaSelections,\n setCurrentProductId,\n errors,\n}: CrudFormGroupComponentProps & {\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n setMediaOptions: React.Dispatch<React.SetStateAction<MediaOption[]>>\n setProductSummary: React.Dispatch<React.SetStateAction<ProductSummary>>\n setVariantPreviews: React.Dispatch<React.SetStateAction<ProductVariantPreview[]>>\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n channelId: string | null\n manualMediaSelections: React.MutableRefObject<Set<string>>\n setCurrentProductId: React.Dispatch<React.SetStateAction<string | null>>\n}) {\n const previousProductIdRef = React.useRef<string | null>(null)\n const initializedProductRef = React.useRef(false)\n React.useEffect(() => {\n const productId = typeof values.productId === 'string' ? values.productId : null\n setCurrentProductId(productId)\n if (!productId) {\n setMediaOptions([])\n setProductSummary(null)\n setVariantPreviews([])\n previousProductIdRef.current = null\n return\n }\n const resolvedProductId = productId as string\n const resolvedChannelId = channelId ?? null\n if (!initializedProductRef.current) {\n previousProductIdRef.current = resolvedProductId\n initializedProductRef.current = true\n } else if (previousProductIdRef.current !== resolvedProductId) {\n previousProductIdRef.current = resolvedProductId\n setValue('defaultMediaId', undefined)\n }\n let cancelled = false\n async function load() {\n try {\n const summary = await resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: resolvedChannelId,\n productCache,\n })\n if (!cancelled) {\n setProductSummary(summary ?? null)\n if (summary) {\n const hasTitle = typeof values.title === 'string' && values.title.trim().length > 0\n if (!hasTitle && summary.title) {\n setValue('title', summary.title)\n }\n const hasDescription =\n typeof values.description === 'string' && values.description.trim().length > 0\n if (!hasDescription && summary.description) {\n setValue('description', summary.description)\n }\n if (\n !values.defaultMediaId &&\n summary.defaultMediaId &&\n !manualMediaSelections.current.has(resolvedProductId)\n ) {\n setValue('defaultMediaId', summary.defaultMediaId)\n }\n }\n }\n const attachments = await resolveProductMediaOptionsWithCache({\n productId: resolvedProductId,\n attachmentCache,\n })\n if (!cancelled) {\n const variants = await resolveVariantPreviewsWithCache({\n productId: resolvedProductId,\n variantCache,\n variantMediaCache,\n })\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.watchers', err)\n }\n }\n void load()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n channelId,\n manualMediaSelections,\n productCache,\n setMediaOptions,\n setProductSummary,\n setValue,\n setVariantPreviews,\n values.defaultMediaId,\n values.description,\n values.productId,\n values.title,\n variantCache,\n variantMediaCache,\n setCurrentProductId,\n ])\n return null\n}\n\nasync function resolveProductSummaryWithCache({\n productId,\n channelId,\n productCache,\n}: {\n productId: string\n channelId: string | null\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n}): Promise<ProductSummaryCacheEntry | null> {\n if (!productId) return null\n const cacheKey = channelId ? `${productId}:${channelId}` : productId\n let summary: ProductSummaryCacheEntry | null | undefined = productCache.current.get(cacheKey)\n if (summary) return summary\n const params = new URLSearchParams({ id: productId, pageSize: '1' })\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/products?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n const product = Array.isArray(payload.items) ? payload.items[0] : null\n summary = product ? mapProductSummary(product) : null\n if (summary) {\n productCache.current.set(cacheKey, summary)\n }\n return summary ?? null\n}\n\nasync function resolveProductMediaOptionsWithCache({\n productId,\n attachmentCache,\n}: {\n productId: string\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n}): Promise<MediaOption[]> {\n if (!productId) return []\n const cached = attachmentCache.current.get(productId) ?? []\n if (cached.length) {\n const deduped = dedupeMediaOptions(cached)\n attachmentCache.current.set(productId, deduped)\n return deduped\n }\n const attachments = dedupeMediaOptions(await loadProductMedia(productId))\n attachmentCache.current.set(productId, attachments)\n return attachments\n}\n\nasync function resolveVariantPreviewsWithCache({\n productId,\n variantCache,\n variantMediaCache,\n}: {\n productId: string\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n}): Promise<ProductVariantPreview[]> {\n if (!productId) return []\n const cached = variantCache.current.get(productId)\n if (cached) return cached\n const variantPayload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/variants?productId=${encodeURIComponent(productId)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(variantPayload.items) ? variantPayload.items : []\n const variants = await Promise.all(\n items.map(async (item) => {\n const preview = mapVariantPreview(item)\n const media = await resolveVariantThumbnail(preview.id, variantMediaCache)\n return {\n ...preview,\n thumbnailId: media?.attachmentId ?? preview.thumbnailId,\n thumbnailUrl: media?.thumbnailUrl ?? preview.thumbnailUrl,\n thumbnailFileName: media?.fileName ?? preview.thumbnailFileName,\n }\n }),\n )\n variantCache.current.set(productId, variants)\n return variants\n}\n\nfunction mapProductSummary(item: Record<string, unknown>): ProductSummaryCacheEntry {\n const pricingSource = item.pricing && typeof item.pricing === 'object' ? item.pricing as Record<string, unknown> : null\n return {\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : null,\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n sku: typeof item.sku === 'string' ? item.sku : null,\n pricing: normalizePricing(pricingSource),\n }\n}\n\nfunction normalizePricing(source: Record<string, unknown> | null): PricingSummary | null {\n if (!source) return null\n const currencyCode = typeof source.currencyCode === 'string'\n ? source.currencyCode\n : typeof source.currency_code === 'string'\n ? source.currency_code\n : null\n const unitPriceNet = typeof source.unitPriceNet === 'string'\n ? source.unitPriceNet\n : typeof source.unit_price_net === 'string'\n ? source.unit_price_net\n : null\n const unitPriceGross = typeof source.unitPriceGross === 'string'\n ? source.unitPriceGross\n : typeof source.unit_price_gross === 'string'\n ? source.unit_price_gross\n : null\n const displayMode = source.displayMode === 'including-tax' || source.display_mode === 'including-tax'\n ? 'including-tax'\n : source.displayMode === 'excluding-tax' || source.display_mode === 'excluding-tax'\n ? 'excluding-tax'\n : null\n return { currencyCode, unitPriceNet, unitPriceGross, displayMode }\n}\n\nasync function loadProductMedia(productId: string): Promise<MediaOption[]> {\n if (!productId) return []\n const normalize = (items: Array<{ id?: string; fileName?: string; thumbnailUrl?: string | null }>) => (\n items\n .filter((item): item is { id: string; fileName: string; thumbnailUrl?: string | null } => (\n typeof item.id === 'string' && typeof item.fileName === 'string'\n ))\n .map((item) => ({\n id: item.id,\n label: item.fileName,\n fileName: item.fileName,\n thumbnailUrl: typeof item.thumbnailUrl === 'string'\n ? item.thumbnailUrl\n : buildAttachmentImageUrl(item.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(item.fileName),\n }),\n }))\n )\n try {\n const primary = await apiCall<AttachmentsResponse>(\n `/api/catalog/product-media?productId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (primary.ok && primary.result?.items) {\n return normalize(primary.result.items)\n }\n } catch (err) {\n console.error('catalog.product-media.lookup', err)\n }\n try {\n const fallback = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product)}&recordId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (fallback.ok && fallback.result?.items) {\n return normalize(fallback.result.items)\n }\n } catch (err) {\n console.error('attachments.lookup', err)\n }\n return []\n}\n\nfunction buildVariantMediaOptions(variants: ProductVariantPreview[]): MediaOption[] {\n return variants\n .map((variant): MediaOption | null => {\n if (!variant.thumbnailId || !variant.thumbnailUrl) return null\n const label = variant.name || variant.sku || 'Variant'\n const fileName = variant.thumbnailFileName ?? `${variant.thumbnailId}.jpg`\n return {\n id: variant.thumbnailId,\n label,\n fileName,\n thumbnailUrl: variant.thumbnailUrl,\n }\n })\n .filter((entry): entry is MediaOption => Boolean(entry))\n}\n\nfunction buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n}: {\n attachments?: MediaOption[] | null\n variants?: ProductVariantPreview[] | null\n summary?: ProductSummary | null\n}): MediaOption[] {\n const merged = dedupeMediaOptions([\n ...(attachments ?? []),\n ...buildVariantMediaOptions(variants ?? []),\n ])\n const defaultId = summary?.defaultMediaId ?? null\n const defaultUrl = summary?.defaultMediaUrl ?? null\n if (defaultId && defaultUrl && !merged.some((entry) => entry.id === defaultId)) {\n const fileName = inferFileNameFromUrl(defaultUrl, defaultId)\n merged.unshift({\n id: defaultId,\n label: fileName,\n fileName,\n thumbnailUrl: defaultUrl,\n })\n }\n return merged\n}\n\nfunction dedupeMediaOptions(entries: MediaOption[] | null | undefined): MediaOption[] {\n if (!Array.isArray(entries)) return []\n const seen = new Set<string>()\n const result: MediaOption[] = []\n for (const entry of entries) {\n if (!entry || typeof entry.id !== 'string') continue\n if (seen.has(entry.id)) continue\n seen.add(entry.id)\n result.push(entry)\n }\n return result\n}\n\nfunction inferFileNameFromUrl(url: string | null, fallbackId: string): string {\n if (typeof url === 'string' && url.length) {\n const cleaned = url.split(/[?#]/)[0]\n const last = cleaned.split('/').pop()\n if (last && last.trim().length) return last\n }\n return `${fallbackId}.jpg`\n}\n\nfunction mapVariantPreview(item: Record<string, unknown>): ProductVariantPreview {\n return {\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string'\n ? item.name\n : typeof item.sku === 'string'\n ? item.sku\n : 'Variant',\n sku: typeof item.sku === 'string' ? item.sku : null,\n thumbnailUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n thumbnailId: null,\n thumbnailFileName: null,\n }\n}\n\nasync function resolveVariantThumbnail(\n variantId: string,\n cache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>,\n): Promise<VariantThumbnailInfo | null> {\n if (!variantId) return null\n if (cache.current.has(variantId)) {\n return cache.current.get(variantId) ?? null\n }\n try {\n const payload = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product_variant)}&recordId=${encodeURIComponent(variantId)}`,\n )\n const items = payload.ok && payload.result?.items ? payload.result.items : []\n const first = items.find((item) => typeof item.id === 'string')\n if (first?.id) {\n const thumbnailUrl = typeof first.thumbnailUrl === 'string'\n ? first.thumbnailUrl\n : buildAttachmentImageUrl(first.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(first.fileName ?? first.id),\n })\n const info: VariantThumbnailInfo = {\n attachmentId: first.id,\n thumbnailUrl: thumbnailUrl ?? null,\n fileName: typeof first.fileName === 'string' ? first.fileName : null,\n }\n cache.current.set(variantId, info)\n return info\n }\n } catch (err) {\n console.error('sales.channels.offer.variantMedia', err)\n }\n const empty: VariantThumbnailInfo = { attachmentId: null, thumbnailUrl: null, fileName: null }\n cache.current.set(variantId, empty)\n return empty\n}\n\nfunction mapProductSearchResult(\n item: Record<string, unknown>,\n channelId?: string | null,\n currentOfferId?: string | null,\n): ProductSearchResult {\n const offers = Array.isArray((item as { offers?: unknown }).offers)\n ? (item as { offers: Array<Record<string, unknown>> }).offers\n : []\n const channelOffer = offers.find((entry) => {\n if (!entry || typeof entry !== 'object') return false\n const offerChannelId = typeof entry.channelId === 'string'\n ? entry.channelId\n : typeof (entry as Record<string, unknown>).channel_id === 'string'\n ? (entry as Record<string, unknown>).channel_id\n : null\n return channelId ? offerChannelId === channelId : false\n }) ?? null\n const existingOfferId = channelOffer && typeof channelOffer.id === 'string' ? channelOffer.id : null\n return {\n id: typeof item.id === 'string' ? item.id : '',\n title: typeof item.title === 'string' ? item.title : '',\n sku: typeof item.sku === 'string' ? item.sku : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n pricing: item.pricing && typeof item.pricing === 'object'\n ? normalizePricing(item.pricing as Record<string, unknown>)\n : null,\n existingOfferId,\n existingOfferTitle:\n channelOffer && typeof channelOffer.title === 'string' ? channelOffer.title : null,\n isCurrentOfferProduct: Boolean(existingOfferId && currentOfferId && existingOfferId === currentOfferId),\n }\n}\n\nfunction formatPriceDisplay(pricing: PricingSummary | null): string {\n if (!pricing) return '\u2014'\n const amount = pricing.displayMode === 'including-tax'\n ? pricing.unitPriceGross ?? pricing.unitPriceNet\n : pricing.unitPriceNet ?? pricing.unitPriceGross\n if (!amount) return pricing.currencyCode ?? '\u2014'\n return `${pricing.currencyCode ?? ''} ${amount}`\n}\n\nfunction PriceOverridesEditor({\n values,\n onChange,\n priceKinds,\n basePrice,\n onRemoveDraft,\n}: {\n values: PriceOverrideDraft[]\n onChange: (next: PriceOverrideDraft[]) => void\n priceKinds: PriceKindSummary[]\n basePrice: PricingSummary | null\n onRemoveDraft?: (draft: PriceOverrideDraft) => Promise<boolean> | boolean\n}) {\n const t = useT()\n const baseAmount = React.useMemo(() => {\n if (!basePrice) return ''\n const net = basePrice.unitPriceNet ?? null\n const gross = basePrice.unitPriceGross ?? null\n if (basePrice.displayMode === 'including-tax') {\n return gross ?? net ?? ''\n }\n if (basePrice.displayMode === 'excluding-tax') {\n return net ?? gross ?? ''\n }\n return net ?? gross ?? ''\n }, [basePrice])\n const baseDefaults = React.useMemo(() => ({\n amount: baseAmount,\n currencyCode: basePrice?.currencyCode ?? null,\n displayMode: basePrice?.displayMode ?? null,\n }), [baseAmount, basePrice?.currencyCode, basePrice?.displayMode])\n const usedKindIdSet = React.useMemo(() => {\n const next = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n next.add(row.priceKindId)\n }\n })\n return next\n }, [values])\n const availableKindCount = priceKinds.reduce(\n (count, kind) => (usedKindIdSet.has(kind.id) ? count : count + 1),\n 0,\n )\n const canAddRow = availableKindCount > 0\n const addRow = React.useCallback(() => {\n const usedIds = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n usedIds.add(row.priceKindId)\n }\n })\n const nextKind = priceKinds.find((kind) => !usedIds.has(kind.id))\n if (!nextKind && priceKinds.length) {\n return\n }\n onChange([\n ...values,\n {\n tempId: crypto.randomUUID?.() ?? Math.random().toString(36).slice(2),\n amount: baseDefaults.amount,\n currencyCode: nextKind?.currencyCode ?? baseDefaults.currencyCode,\n displayMode: nextKind?.displayMode ?? baseDefaults.displayMode,\n priceKindId: nextKind?.id ?? null,\n priceKindCode: nextKind?.code ?? nextKind?.title ?? null,\n },\n ])\n }, [baseDefaults, onChange, priceKinds, values])\n\n const updateRow = React.useCallback((tempId: string, patch: Partial<PriceOverrideDraft>) => {\n onChange(values.map((row) => (row.tempId === tempId ? { ...row, ...patch } : row)))\n }, [onChange, values])\n\n const removeRow = React.useCallback(async (row: PriceOverrideDraft) => {\n const allowRemoval = await onRemoveDraft?.(row)\n if (allowRemoval === false) return\n onChange(values.filter((entry) => entry.tempId !== row.tempId))\n }, [onChange, onRemoveDraft, values])\n\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded border bg-muted/50 px-3 py-2\">\n <div className=\"text-xs uppercase text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceLabel', 'Original product price')}\n </div>\n <div className=\"text-base font-semibold\">\n {basePrice ? formatPriceDisplay(basePrice) : t('sales.channels.offers.pricing.basePriceMissing', 'No price found')}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceHelp', 'Shown to shoppers when no override is configured.')}\n </div>\n </div>\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {t('sales.channels.offers.pricing.help', 'Provide overrides for price kinds when this offer is active.')}\n </p>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addRow} disabled={!canAddRow}>\n {t('sales.channels.offers.pricing.add', 'Add price')}\n </Button>\n </div>\n {!canAddRow ? (\n <p className=\"text-xs text-muted-foreground\">\n {priceKinds.length\n ? t('sales.channels.offers.pricing.allKindsUsed', 'Each price kind already has an override.')\n : t('sales.channels.offers.pricing.noKindsAvailable', 'Define a price kind before adding overrides.')}\n </p>\n ) : null}\n </div>\n <div className=\"flex items-center justify-between\">\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.overrideHint', 'Overrides take precedence over the original product price.')}\n </p>\n </div>\n {values.length ? (\n <div className=\"space-y-2\">\n {values.map((row) => (\n <div key={row.tempId} className=\"grid gap-2 rounded border p-3 md:grid-cols-3\">\n <Select\n value={row.priceKindId || undefined}\n onValueChange={(value) => {\n const next = priceKinds.find((kind) => kind.id === value)\n updateRow(row.tempId, {\n priceKindId: next?.id ?? null,\n priceKindCode: next?.code ?? next?.title ?? null,\n currencyCode: next?.currencyCode ?? null,\n displayMode: next?.displayMode ?? null,\n })\n }}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('sales.channels.offers.pricing.selectKind', 'Select price kind')} />\n </SelectTrigger>\n <SelectContent>\n {priceKinds.map((kind) => (\n <SelectItem\n key={kind.id}\n value={kind.id}\n disabled={usedKindIdSet.has(kind.id) && row.priceKindId !== kind.id}\n >\n {kind.title ?? kind.code ?? kind.id}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <div className=\"relative\">\n {(row.currencyCode ?? basePrice?.currencyCode) ? (\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-xs font-semibold text-muted-foreground\">\n {row.currencyCode ?? basePrice?.currencyCode}\n </span>\n ) : null}\n <Input\n inputClassName={cn(row.currencyCode || basePrice?.currencyCode ? 'pl-13' : '')}\n type=\"number\"\n placeholder={t('sales.channels.offers.pricing.amount', 'Amount')}\n value={row.amount ?? ''}\n onChange={(event) => updateRow(row.tempId, { amount: event.target.value })}\n />\n </div>\n <div className=\"flex flex-col justify-between gap-2 text-xs text-muted-foreground sm:flex-row sm:items-center\">\n <span>\n {row.displayMode === 'including-tax'\n ? t('sales.channels.offers.pricing.includingTax', 'Including tax')\n : t('sales.channels.offers.pricing.excludingTax', 'Excluding tax')}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1 px-2 font-normal text-destructive hover:text-destructive focus-visible:text-destructive\"\n onClick={() => { void removeRow(row) }}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n {t('sales.channels.offers.pricing.remove', 'Remove')}\n </Button>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.empty', 'No overrides yet.')}\n {basePrice ? (\n <>\n {' '}\n {t(\n 'sales.channels.offers.pricing.emptyFallback',\n 'Using {price} from the product until you add overrides.',\n { price: formatPriceDisplay(basePrice) },\n )}\n </>\n ) : null}\n </p>\n )}\n </div>\n )\n}\n\nfunction ProductOverviewCard({ summary, variants }: { summary: ProductSummary; variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!summary) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSummaryPlaceholder', 'Select a product to preview its media, price, and variants.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-4\">\n <div className=\"flex gap-3\">\n <div className=\"h-16 w-16 overflow-hidden rounded border bg-muted\">\n {summary.defaultMediaUrl ? (\n <img src={summary.defaultMediaUrl} alt={summary.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex-1\">\n <div className=\"text-sm font-semibold\">{summary.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {summary.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {summary.sku}</div>\n ) : null}\n <div className=\"text-sm\">\n <span className=\"text-muted-foreground\">{t('sales.channels.offers.form.productPriceLabel', 'Base price')}:</span>{' '}\n <span className=\"font-semibold\">{formatPriceDisplay(summary.pricing)}</span>\n </div>\n </div>\n </div>\n {summary.description ? (\n <p className=\"text-sm text-muted-foreground\">{summary.description}</p>\n ) : null}\n <ProductVariantsList variants={variants} />\n </div>\n )\n}\n\nfunction ProductVariantsList({ variants }: { variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!variants.length) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.variantsEmpty', 'No variants available for this product.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-2\">\n <div className=\"text-sm font-medium\">{t('sales.channels.offers.form.variantsTitle', 'Variants')}</div>\n <div className=\"space-y-2 max-h-64 overflow-y-auto pr-1\">\n {variants.map((variant) => (\n <div key={variant.id} className=\"flex gap-3 rounded border bg-card p-2\">\n <div className=\"h-10 w-10 overflow-hidden rounded border bg-muted\">\n {variant.thumbnailUrl ? (\n <img src={variant.thumbnailUrl} alt={variant.name} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-4 w-4\" />\n </div>\n )}\n </div>\n <div className=\"min-w-0\">\n <div className=\"text-xs font-medium\">{variant.name}</div>\n {variant.sku ? (\n <div className=\"text-overline text-muted-foreground\">SKU \u00B7 {variant.sku}</div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </div>\n )\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport Link from 'next/link'\nimport { useRouter } from 'next/navigation'\nimport { CrudForm, type CrudField, type CrudFormGroup, type CrudFormGroupComponentProps } from '@open-mercato/ui/backend/CrudForm'\nimport { collectCustomFieldValues } from '@open-mercato/ui/backend/utils/customFieldValues'\nimport { createCrud, updateCrud, deleteCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError, type CrudServerFieldErrors } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { readApiResultOrThrow, apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader, extractOptimisticLockConflict } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport { Loader2, Search, Image as ImageIcon, Trash2 } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { extractCustomFieldEntries } from '@open-mercato/shared/lib/crud/custom-fields-client'\nimport { E } from '#generated/entities.ids.generated'\nimport { buildAttachmentImageUrl, slugifyAttachmentFileName } from '@open-mercato/core/modules/attachments/lib/imageUrls'\nimport { cn } from '@open-mercato/shared/lib/utils'\n\ntype PriceKindSummary = {\n id: string\n code: string | null\n title: string | null\n displayMode: 'including-tax' | 'excluding-tax'\n currencyCode: string | null\n}\n\ntype PriceOverrideDraft = {\n tempId: string\n priceId?: string | null\n priceKindId?: string | null\n priceKindCode?: string | null\n currencyCode?: string | null\n displayMode?: 'including-tax' | 'excluding-tax' | null\n amount?: string\n /** The price row's version, for the per-price optimistic-lock header (#2332). */\n updatedAt?: string | null\n}\n\nexport type OfferFormValues = {\n channelId: string | null\n productId: string | null\n title: string\n description: string\n defaultMediaId?: string | null\n isActive: boolean\n priceOverrides: PriceOverrideDraft[]\n updatedAt?: string | null\n} & Record<string, unknown>\n\ntype ChannelOfferFormProps = {\n channelId?: string\n offerId?: string\n mode: 'create' | 'edit'\n}\n\ntype OfferResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype PriceResponse = {\n items?: Array<Record<string, unknown>>\n}\n\ntype AttachmentsResponse = {\n items?: Array<{ id?: string; fileName?: string; url?: string; thumbnailUrl?: string | null }>\n}\n\ntype ProductSummaryCacheEntry = {\n title: string\n description: string | null\n defaultMediaId: string | null\n defaultMediaUrl: string | null\n sku: string | null\n pricing: PricingSummary | null\n}\n\ntype MediaOption = { id: string; label: string; fileName: string; thumbnailUrl?: string | null }\n\ntype PricingSummary = {\n currencyCode: string | null\n unitPriceNet: string | null\n unitPriceGross: string | null\n displayMode: 'including-tax' | 'excluding-tax' | null\n}\n\ntype ProductVariantPreview = {\n id: string\n name: string\n sku: string | null\n thumbnailUrl: string | null\n thumbnailId: string | null\n thumbnailFileName: string | null\n}\n\ntype ProductSummary = ProductSummaryCacheEntry | null\n\ntype ProductSearchResult = {\n id: string\n title: string\n sku: string | null\n defaultMediaUrl: string | null\n pricing: PricingSummary | null\n existingOfferId: string | null\n existingOfferTitle: string | null\n isCurrentOfferProduct: boolean\n}\n\nconst UUID_REGEX = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-5][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/\nconst MAX_LIST_PAGE_SIZE = 100\ntype VariantThumbnailInfo = { attachmentId: string | null; thumbnailUrl: string | null; fileName: string | null }\n\nexport function ChannelOfferForm({ channelId: lockedChannelId, offerId, mode }: ChannelOfferFormProps) {\n const t = useT()\n const router = useRouter()\n const [initialValues, setInitialValues] = React.useState<OfferFormValues | null>(mode === 'create'\n ? {\n channelId: lockedChannelId ?? null,\n productId: null,\n title: '',\n description: '',\n defaultMediaId: null,\n isActive: true,\n priceOverrides: [],\n }\n : null)\n const [loading, setLoading] = React.useState(mode === 'edit')\n const [error, setError] = React.useState<string | null>(null)\n const [priceKinds, setPriceKinds] = React.useState<PriceKindSummary[]>([])\n const [mediaOptions, setMediaOptions] = React.useState<MediaOption[]>([])\n const attachmentCache = React.useRef<Map<string, MediaOption[]>>(new Map())\n const productCache = React.useRef<Map<string, ProductSummaryCacheEntry>>(new Map())\n const [productSummary, setProductSummary] = React.useState<ProductSummary>(null)\n const [variantPreviews, setVariantPreviews] = React.useState<ProductVariantPreview[]>([])\n const variantCache = React.useRef<Map<string, ProductVariantPreview[]>>(new Map())\n const variantMediaCache = React.useRef<Map<string, VariantThumbnailInfo>>(new Map())\n const [selectedChannelId, setSelectedChannelId] = React.useState<string | null>(lockedChannelId ?? null)\n const manualMediaSelections = React.useRef<Set<string>>(new Set())\n // Map of the loaded price-override id \u2192 its `updatedAt`, so deletes during the\n // offer save can send the price's own optimistic-lock version (#2332).\n const initialPriceVersionsRef = React.useRef<Map<string, string | null>>(new Map())\n const [currentProductId, setCurrentProductId] = React.useState<string | null>(null)\n React.useEffect(() => {\n if (initialValues) {\n initialPriceVersionsRef.current = collectPriceVersions(initialValues.priceOverrides)\n } else {\n initialPriceVersionsRef.current = new Map()\n }\n }, [initialValues])\n const channelOffersHref = React.useMemo(\n () => buildChannelOffersHref(lockedChannelId),\n [lockedChannelId],\n )\n\n React.useEffect(() => {\n if (lockedChannelId) {\n setSelectedChannelId(lockedChannelId)\n } else if (initialValues?.channelId) {\n setSelectedChannelId(initialValues.channelId)\n }\n }, [initialValues?.channelId, lockedChannelId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string') {\n setCurrentProductId(initialValues.productId)\n }\n }, [initialValues?.productId])\n\n React.useEffect(() => {\n if (typeof initialValues?.productId === 'string' && initialValues?.defaultMediaId === null) {\n manualMediaSelections.current.add(initialValues.productId)\n }\n }, [initialValues?.defaultMediaId, initialValues?.productId])\n\n React.useEffect(() => {\n if (mode !== 'edit') return\n const productId = typeof initialValues?.productId === 'string' ? initialValues.productId : null\n if (!productId) return\n const resolvedProductId = productId\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof initialValues?.channelId === 'string' ? initialValues.channelId : null)\n let cancelled = false\n async function hydrateExistingProduct() {\n try {\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n resolveProductMediaOptionsWithCache({ productId: resolvedProductId, attachmentCache }),\n resolveVariantPreviewsWithCache({ productId: resolvedProductId, variantCache, variantMediaCache }),\n ])\n if (!cancelled) {\n setProductSummary(summary ?? null)\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.initialHydrate', err)\n }\n }\n void hydrateExistingProduct()\n return () => {\n cancelled = true\n }\n }, [\n attachmentCache,\n initialValues?.channelId,\n initialValues?.productId,\n lockedChannelId,\n mode,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n ])\n\n React.useEffect(() => {\n async function loadKinds() {\n const mapItems = (items: Array<Record<string, unknown>>): PriceKindSummary[] =>\n items.map((item): PriceKindSummary => {\n const displayMode =\n item.displayMode === 'including-tax' || item.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax'\n return {\n id: typeof item.id === 'string' ? item.id : '',\n code: typeof item.code === 'string' ? item.code : null,\n title: typeof item.title === 'string' ? item.title : null,\n currencyCode:\n typeof item.currencyCode === 'string'\n ? item.currencyCode\n : typeof item.currency_code === 'string'\n ? item.currency_code\n : null,\n displayMode,\n }\n })\n const endpoints = [\n `/api/sales/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n `/api/catalog/price-kinds?pageSize=${MAX_LIST_PAGE_SIZE}`,\n ]\n try {\n for (const endpoint of endpoints) {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n endpoint,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setPriceKinds(mapItems(items))\n return\n } catch (err) {\n console.error('sales.channels.price-kinds.fetch', { endpoint, err })\n }\n }\n setPriceKinds([])\n } catch (err) {\n console.error('catalog.price-kinds.list', err)\n }\n }\n void loadKinds()\n }, [])\n\n React.useEffect(() => {\n if (mode !== 'edit' || !offerId) return\n const offerKey = offerId\n let cancelled = false\n async function loadOffer() {\n setLoading(true)\n setError(null)\n try {\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/offers?id=${encodeURIComponent(offerKey)}&pageSize=1`,\n undefined,\n { errorMessage: t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.') },\n )\n const offer = Array.isArray(payload.items) ? payload.items[0] : null\n if (!offer) throw new Error(t('sales.channels.offers.errors.notFound', 'Offer not found.'))\n const values = mapOfferToFormValues(offer, lockedChannelId)\n const pricePayload = await readApiResultOrThrow<PriceResponse>(\n `/api/catalog/prices?offerId=${encodeURIComponent(offer.id as string)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const priceItems = Array.isArray(pricePayload.items) ? pricePayload.items : []\n values.priceOverrides = priceItems.map(mapPriceRow)\n let preloadedMedia: MediaOption[] = []\n let preloadedVariants: ProductVariantPreview[] = []\n let preloadedSummary: ProductSummary | null = null\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (productId) {\n try {\n const hydrationChannelId = selectedChannelId\n ?? lockedChannelId\n ?? (typeof values.channelId === 'string' ? values.channelId : null)\n const [summary, attachments, variants] = await Promise.all([\n resolveProductSummaryWithCache({\n productId,\n channelId: hydrationChannelId ?? null,\n productCache,\n }),\n loadProductMedia(productId),\n resolveVariantPreviewsWithCache({ productId, variantCache, variantMediaCache }),\n ])\n preloadedSummary = summary ?? null\n preloadedVariants = variants\n preloadedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(productId, preloadedMedia)\n } catch (err) {\n console.error('sales.channels.offer.media.preload', err)\n }\n }\n if (!cancelled) {\n setInitialValues(values)\n setProductSummary(preloadedSummary)\n setVariantPreviews(preloadedVariants)\n setMediaOptions(preloadedMedia)\n }\n } catch (err) {\n console.error('sales.channels.offer.load', err)\n if (!cancelled) setError(t('sales.channels.offers.errors.loadOffer', 'Failed to load offer.'))\n } finally {\n if (!cancelled) setLoading(false)\n }\n }\n void loadOffer()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n lockedChannelId,\n mode,\n offerId,\n productCache,\n selectedChannelId,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n t,\n variantCache,\n variantMediaCache,\n ])\n\n const fields = React.useMemo<CrudField[]>(() => [\n {\n id: 'channelId',\n label: t('sales.channels.offers.form.channel', 'Channel'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ChannelSelectInput\n value={(value as string | null) ?? lockedChannelId ?? null}\n onChange={(next) => {\n setValue(next ?? null)\n setSelectedChannelId(next ?? null)\n }}\n disabled={!!lockedChannelId}\n showDetailsLink\n />\n ),\n },\n {\n id: 'productId',\n label: t('sales.channels.offers.form.product', 'Product'),\n type: 'custom',\n required: true,\n component: ({ value, setValue }) => (\n <ProductSelectInput\n value={(value as string | null) ?? null}\n onChange={(next) => setValue(next)}\n channelId={selectedChannelId}\n currentOfferId={offerId ?? null}\n />\n ),\n },\n {\n id: 'defaultMediaId',\n label: t('sales.channels.offers.form.defaultMedia', 'Default media'),\n type: 'custom',\n component: ({ value, setValue }) => (\n <DefaultMediaSelect\n value={(value as string | null | undefined) ?? null}\n onChange={(next) => {\n setValue(next)\n if (!currentProductId) return\n if (next === null || next === undefined) {\n manualMediaSelections.current.add(currentProductId)\n } else {\n manualMediaSelections.current.delete(currentProductId)\n }\n }}\n options={mediaOptions}\n productThumbnail={productSummary?.defaultMediaUrl ?? null}\n hasProduct={Boolean(productSummary)}\n productDefaultMediaId={productSummary?.defaultMediaId ?? null}\n />\n ),\n },\n {\n id: 'title',\n label: t('sales.channels.offers.form.title', 'Title'),\n type: 'text',\n required: true,\n },\n {\n id: 'description',\n label: t('sales.channels.offers.form.description', 'Description'),\n type: 'textarea',\n },\n {\n id: 'isActive',\n label: t('sales.channels.offers.form.active', 'Active'),\n type: 'checkbox',\n },\n ], [lockedChannelId, mediaOptions, productSummary, selectedChannelId, t, currentProductId])\n\n const handleOverrideRemove = React.useCallback(async (draft: PriceOverrideDraft) => {\n const priceId = typeof draft?.priceId === 'string' ? draft.priceId : null\n if (!priceId) return true\n if (mode !== 'edit') return true\n try {\n await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(draft.updatedAt),\n () => deleteCrud('catalog/prices', priceId, {\n errorMessage: t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'),\n }),\n )\n initialPriceVersionsRef.current.delete(priceId)\n return true\n } catch (err) {\n if (surfaceRecordConflict(err, t)) return false\n console.error('sales.channels.pricing.remove', err)\n flash(t('sales.channels.offers.errors.removePrice', 'Failed to remove price override.'), 'error')\n return false\n }\n }, [mode, t])\n\n const groups = React.useMemo<CrudFormGroup[]>(() => [\n { id: 'associations', column: 1, title: t('sales.channels.offers.form.groups.associations', 'Associations'), fields: ['channelId'] },\n {\n id: 'product',\n column: 1,\n title: t('sales.channels.offers.form.productGroup', 'Product'),\n description: t('sales.channels.offers.form.productGroupHelp', 'Search the catalog and pick the product you want to customize for this channel.'),\n fields: ['productId'],\n },\n {\n id: 'productSummary',\n column: 2,\n title: t('sales.channels.offers.form.productSummaryTitle', 'Product summary'),\n component: () => (\n <ProductOverviewCard summary={productSummary} variants={variantPreviews} />\n ),\n },\n {\n id: 'media',\n column: 1,\n title: t('sales.channels.offers.form.mediaGroupTitle', 'Default media override'),\n fields: ['defaultMediaId'],\n },\n { id: 'content', column: 1, title: t('sales.channels.offers.form.groups.content', 'Content'), fields: ['title', 'description', 'isActive'] },\n {\n id: 'pricing',\n column: 1,\n title: t('sales.channels.offers.form.groups.pricing', 'Price overrides'),\n component: ({ values, setValue }) => (\n <PriceOverridesEditor\n values={Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []}\n onChange={(next) => setValue('priceOverrides', next)}\n priceKinds={priceKinds}\n basePrice={productSummary?.pricing ?? null}\n onRemoveDraft={handleOverrideRemove}\n />\n ),\n },\n {\n id: 'customFields',\n column: 2,\n title: t('entities.customFields.title', 'Custom attributes'),\n kind: 'customFields',\n },\n {\n id: 'watchers',\n column: 1,\n bare: true,\n component: ({ values, setValue, errors }) => (\n <OfferFormWatchers\n values={values}\n setValue={setValue}\n errors={errors}\n productCache={productCache}\n attachmentCache={attachmentCache}\n setMediaOptions={setMediaOptions}\n setProductSummary={setProductSummary}\n setVariantPreviews={setVariantPreviews}\n variantCache={variantCache}\n variantMediaCache={variantMediaCache}\n channelId={selectedChannelId}\n manualMediaSelections={manualMediaSelections}\n setCurrentProductId={setCurrentProductId}\n />\n ),\n },\n ], [\n attachmentCache,\n handleOverrideRemove,\n manualMediaSelections,\n priceKinds,\n productCache,\n productSummary,\n selectedChannelId,\n setMediaOptions,\n setCurrentProductId,\n t,\n variantPreviews,\n ])\n\n const handleSubmit = React.useCallback(async (values: OfferFormValues) => {\n const channelId = typeof values.channelId === 'string' && values.channelId.length\n ? values.channelId\n : selectedChannelId ?? lockedChannelId\n const productId = typeof values.productId === 'string' ? values.productId : null\n if (!channelId || !productId) {\n throw new Error(t('sales.channels.offers.errors.requiredFields', 'Choose a channel and product.'))\n }\n const resolvedDefaultMediaId = typeof values.defaultMediaId === 'string' && values.defaultMediaId.trim().length\n ? values.defaultMediaId\n : values.defaultMediaId === null\n ? null\n : undefined\n const basePayload: Record<string, unknown> = {\n channelId,\n productId,\n title: values.title?.trim() || undefined,\n description: values.description?.trim() || undefined,\n isActive: values.isActive !== false,\n }\n if (resolvedDefaultMediaId !== undefined) {\n basePayload.defaultMediaId = resolvedDefaultMediaId\n }\n const attachmentLookup = attachmentCache.current.get(productId) ?? []\n const mediaMap = new Map(attachmentLookup.map((entry) => [entry.id, entry.fileName]))\n if (typeof resolvedDefaultMediaId === 'string' && mediaMap.has(resolvedDefaultMediaId)) {\n const fileName = mediaMap.get(resolvedDefaultMediaId) ?? null\n basePayload.defaultMediaUrl = buildAttachmentImageUrl(resolvedDefaultMediaId, {\n slug: slugifyAttachmentFileName(fileName),\n })\n } else if (resolvedDefaultMediaId === null) {\n basePayload.defaultMediaUrl = null\n }\n const customFields = collectCustomFieldValues(values)\n if (Object.keys(customFields).length) basePayload.customFields = customFields\n const overrides = Array.isArray(values.priceOverrides) ? values.priceOverrides as PriceOverrideDraft[] : []\n const priceWithoutKind = overrides.find((entry) => {\n const amount = typeof entry.amount === 'string' ? entry.amount.trim() : entry.amount\n const hasAmount = typeof amount === 'string' ? amount.length > 0 : amount !== undefined && amount !== null\n const hasExistingPrice = typeof entry.priceId === 'string' && entry.priceId.length > 0\n const hasCurrency = typeof entry.currencyCode === 'string' && entry.currencyCode.length > 0\n return !entry.priceKindId && (hasAmount || hasExistingPrice || hasCurrency)\n })\n if (priceWithoutKind) {\n throw createCrudFormError(t('sales.channels.offers.errors.priceKindRequired', 'Select a price kind for each override.'), {})\n }\n const duplicateKind = (() => {\n const seen = new Set<string>()\n for (const entry of overrides) {\n const kindId = typeof entry.priceKindId === 'string' ? entry.priceKindId : null\n if (!kindId) continue\n if (seen.has(kindId)) return kindId\n seen.add(kindId)\n }\n return null\n })()\n if (duplicateKind) {\n throw createCrudFormError(\n t('sales.channels.offers.errors.priceKindDuplicate', 'Each price kind can only be overridden once.'),\n {},\n )\n }\n const submittedPriceIds = collectPriceIds(overrides)\n const deletedIdSet = new Set<string>()\n initialPriceVersionsRef.current.forEach((_version, id) => {\n if (!submittedPriceIds.has(id)) deletedIdSet.add(id)\n })\n const deletedIds = Array.from(deletedIdSet)\n const deletedVersions = new Map(deletedIds.map((id) => [id, initialPriceVersionsRef.current.get(id) ?? null]))\n let savedId = offerId ?? null\n try {\n if (mode === 'create') {\n const res = await createCrud<{ id?: string; offerId?: string }>('catalog/offers', basePayload, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = res?.result?.offerId ?? res?.result?.id ?? null\n } else if (offerId) {\n await updateCrud('catalog/offers', { id: offerId, ...basePayload }, {\n errorMessage: t('sales.channels.offers.errors.save', 'Failed to save offer.'),\n })\n savedId = offerId\n }\n } catch (err) {\n // Let an optimistic-lock 409 propagate untouched so CrudForm's\n // extractOptimisticLockConflict still sees the top-level `code` /\n // `currentUpdatedAt` / `expectedUpdatedAt` and surfaces the unified\n // conflict bar. Re-wrapping via createCrudFormError below would drop them.\n if (extractOptimisticLockConflict(err)) {\n throw err\n }\n const details = (err as { details?: unknown })?.details\n const rawFieldErrors = (err as { fieldErrors?: unknown })?.fieldErrors\n const fieldErrors = rawFieldErrors && typeof rawFieldErrors === 'object'\n ? (rawFieldErrors as CrudServerFieldErrors)\n : undefined\n const status = (err as { status?: number })?.status\n const message = typeof (err as { message?: unknown }).message === 'string' && (err as { message: string }).message.trim().length\n ? (err as { message: string }).message\n : t(\n 'sales.channels.offers.errors.duplicateProduct',\n 'This product already has an offer in this channel.',\n )\n throw createCrudFormError(\n message,\n fieldErrors,\n { status, details },\n )\n }\n if (savedId) {\n await syncPriceOverrides({\n overrides,\n deletedIds,\n deletedVersions,\n offerId: savedId,\n channelId,\n productId,\n })\n initialPriceVersionsRef.current = collectPriceVersions(overrides)\n }\n flash(t('sales.channels.offers.messages.saved', 'Offer saved.'), 'success')\n router.push(buildChannelOffersHref(channelId))\n }, [attachmentCache, lockedChannelId, mode, offerId, router, selectedChannelId, t])\n\n const handleDelete = React.useCallback(async () => {\n if (!offerId) return\n await deleteCrud('catalog/offers', offerId, {\n errorMessage: t('sales.channels.offers.errors.delete', 'Failed to delete offer.'),\n })\n flash(t('sales.channels.offers.messages.deleted', 'Offer deleted.'), 'success')\n const targetChannel = initialValues?.channelId ?? lockedChannelId ?? ''\n router.push(buildChannelOffersHref(targetChannel))\n }, [initialValues?.channelId, lockedChannelId, offerId, router, t])\n\n return (\n <div>\n {error ? (\n <div className=\"mb-4 rounded border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive\">\n {error}\n </div>\n ) : null}\n <CrudForm<OfferFormValues>\n title={mode === 'create'\n ? t('sales.channels.offers.form.createTitle', 'Create offer')\n : t('sales.channels.offers.form.editTitle', 'Edit offer')}\n entityId={E.catalog.catalog_offer}\n fields={fields}\n groups={groups}\n initialValues={initialValues ?? undefined}\n optimisticLockUpdatedAt={initialValues?.updatedAt}\n isLoading={loading}\n loadingMessage={t('sales.channels.offers.form.loading', 'Loading offer\u2026')}\n submitLabel={mode === 'create'\n ? t('sales.channels.offers.form.createSubmit', 'Create offer')\n : t('sales.channels.offers.form.updateSubmit', 'Save changes')}\n cancelHref={channelOffersHref}\n backHref={channelOffersHref}\n onSubmit={handleSubmit}\n onDelete={mode === 'edit' ? handleDelete : undefined}\n deleteVisible={mode === 'edit'}\n deleteRedirect={channelOffersHref}\n />\n </div>\n )\n}\n\nfunction mapOfferToFormValues(item: Record<string, unknown>, lockedChannelId?: string | null): OfferFormValues {\n const values: OfferFormValues = {\n channelId: typeof item.channelId === 'string'\n ? item.channelId\n : typeof item.channel_id === 'string'\n ? item.channel_id\n : lockedChannelId ?? null,\n productId: typeof item.productId === 'string'\n ? item.productId\n : typeof item.product_id === 'string'\n ? item.product_id\n : null,\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : '',\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n isActive: item.isActive === true || item.is_active === true,\n priceOverrides: [],\n updatedAt: typeof item.updatedAt === 'string'\n ? item.updatedAt\n : typeof item.updated_at === 'string'\n ? item.updated_at\n : null,\n }\n mergeCustomFieldValues(values, item)\n return values\n}\n\nfunction mapPriceRow(row: Record<string, unknown>): PriceOverrideDraft {\n return {\n tempId: String(row.id ?? crypto.randomUUID?.() ?? Math.random()),\n priceId: typeof row.id === 'string' ? row.id : undefined,\n priceKindId: typeof row.priceKindId === 'string'\n ? row.priceKindId\n : typeof row.price_kind_id === 'string'\n ? row.price_kind_id\n : undefined,\n priceKindCode: typeof row.priceKindCode === 'string'\n ? row.priceKindCode\n : typeof row.price_kind_code === 'string'\n ? row.price_kind_code\n : null,\n currencyCode: typeof row.currencyCode === 'string'\n ? row.currencyCode\n : typeof row.currency_code === 'string'\n ? row.currency_code\n : null,\n displayMode: row.displayMode === 'including-tax' || row.display_mode === 'including-tax'\n ? 'including-tax'\n : 'excluding-tax',\n amount: typeof row.unitPriceNet === 'string'\n ? row.unitPriceNet\n : typeof row.unit_price_net === 'string'\n ? row.unit_price_net\n : typeof row.unitPriceGross === 'string'\n ? row.unitPriceGross\n : typeof row.unit_price_gross === 'string'\n ? row.unit_price_gross\n : '',\n updatedAt: typeof row.updatedAt === 'string'\n ? row.updatedAt\n : typeof row.updated_at === 'string'\n ? row.updated_at\n : null,\n }\n}\n\nfunction collectPriceIds(source: PriceOverrideDraft[] | null | undefined): Set<string> {\n if (!Array.isArray(source)) return new Set()\n const ids = source\n .map((entry) => (typeof entry?.priceId === 'string' ? entry.priceId : null))\n .filter((id): id is string => Boolean(id))\n return new Set(ids)\n}\n\nfunction collectPriceVersions(source: PriceOverrideDraft[] | null | undefined): Map<string, string | null> {\n const versions = new Map<string, string | null>()\n if (!Array.isArray(source)) return versions\n for (const entry of source) {\n if (typeof entry?.priceId === 'string' && entry.priceId) {\n versions.set(entry.priceId, typeof entry.updatedAt === 'string' ? entry.updatedAt : null)\n }\n }\n return versions\n}\n\nfunction mergeCustomFieldValues(target: Record<string, unknown>, source: Record<string, unknown> | null | undefined) {\n Object.assign(target, extractCustomFieldEntries(source ?? {}))\n}\n\nfunction buildChannelOffersHref(channelId?: string | null): string {\n return channelId && channelId.length\n ? `/backend/sales/channels/${channelId}/edit?tab=offers`\n : '/backend/sales/channels/offers'\n}\n\nasync function syncPriceOverrides(params: {\n overrides: PriceOverrideDraft[]\n deletedIds: string[]\n deletedVersions: Map<string, string | null>\n offerId: string\n channelId: string\n productId: string\n}) {\n const { overrides, deletedIds, deletedVersions, offerId, channelId, productId } = params\n for (const draft of overrides) {\n if (!draft.priceKindId || !draft.amount) continue\n const amount = Number(draft.amount)\n if (Number.isNaN(amount)) continue\n const payload: Record<string, unknown> = {\n offerId,\n productId,\n channelId,\n priceKindId: draft.priceKindId,\n currencyCode: draft.currencyCode ?? undefined,\n }\n if (draft.displayMode === 'including-tax') {\n payload.unitPriceGross = amount\n } else {\n payload.unitPriceNet = amount\n }\n if (draft.priceId) {\n // Send the PRICE's own version, overriding the offer header the parent\n // CrudForm submit scope put on the stack (otherwise the price guard would\n // compare the offer's `updated_at` and 409 falsely). #2332.\n const priceId = draft.priceId\n await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(draft.updatedAt),\n () => updateCrud('catalog/prices', { id: priceId, ...payload }),\n )\n } else {\n await createCrud('catalog/prices', payload)\n }\n }\n const uniqueDeletedIds = Array.from(new Set(\n deletedIds.filter((id): id is string => typeof id === 'string' && id.length > 0),\n ))\n for (const id of uniqueDeletedIds) {\n if (!id) continue\n try {\n await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(deletedVersions.get(id) ?? null),\n () => deleteCrud('catalog/prices', id),\n )\n } catch (err) {\n console.error('catalog.prices.delete', err)\n }\n }\n}\n\nfunction ChannelSelectInput({\n value,\n onChange,\n disabled,\n showDetailsLink,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n disabled?: boolean\n showDetailsLink?: boolean\n}) {\n const t = useT()\n const [options, setOptions] = React.useState<Array<{ id: string; name: string; code: string | null }>>([])\n const selectedOption = React.useMemo(\n () => (value ? options.find((opt) => opt.id === value) ?? null : null),\n [options, value],\n )\n React.useEffect(() => {\n async function load() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n setOptions(items.map((item) => ({\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string' ? item.name : '',\n code: typeof item.code === 'string' ? item.code : null,\n })))\n } catch (err) {\n console.error('sales.channels.options', err)\n }\n }\n void load()\n }, [])\n React.useEffect(() => {\n const channelIdToLoad = typeof value === 'string' ? value : null\n if (!channelIdToLoad || selectedOption) return\n const resolvedChannelId = channelIdToLoad\n let cancelled = false\n async function loadSingle() {\n try {\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/sales/channels?id=${encodeURIComponent(resolvedChannelId)}&pageSize=1`,\n undefined,\n { fallback: { items: [] } },\n )\n const item = Array.isArray(payload.items) ? payload.items[0] : null\n if (!item || cancelled) return\n const entry = {\n id: typeof item.id === 'string' ? item.id : resolvedChannelId,\n name: typeof item.name === 'string' ? item.name : resolvedChannelId,\n code: typeof item.code === 'string' ? item.code : null,\n }\n setOptions((prev) => {\n if (prev.some((opt) => opt.id === entry.id)) return prev\n return [...prev, entry]\n })\n } catch (err) {\n console.error('sales.channels.lookup', err)\n }\n }\n void loadSingle()\n return () => { cancelled = true }\n }, [selectedOption, value])\n\n if (disabled && value) {\n const label = selectedOption?.name ?? value\n const detail = selectedOption?.code ?? null\n return (\n <div className=\"flex items-center justify-between gap-3 rounded border bg-muted px-3 py-2 text-sm\">\n <div className=\"min-w-0\">\n <div className=\"font-medium truncate\">{label}</div>\n {detail ? (\n <div className=\"text-xs text-muted-foreground truncate\">{detail}</div>\n ) : null}\n </div>\n {showDetailsLink ? (\n <Link href={`/backend/sales/channels/${value}/edit`} className=\"text-xs font-medium text-primary hover:underline\">\n {t('sales.channels.offers.form.channelDetails', 'Details')}\n </Link>\n ) : null}\n </div>\n )\n }\n return (\n <Select value={value || undefined} onValueChange={(next) => onChange(next || null)}>\n <SelectTrigger>\n <SelectValue placeholder={t('sales.channels.offers.form.channelPlaceholder', 'Select channel')} />\n </SelectTrigger>\n <SelectContent>\n {options.map((opt) => (\n <SelectItem key={opt.id} value={opt.id}>\n {opt.code ? `${opt.name} (${opt.code})` : opt.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )\n}\n\nfunction ProductSelectInput({\n value,\n onChange,\n channelId,\n currentOfferId,\n}: {\n value: string | null\n onChange: (next: string | null) => void\n channelId: string | null\n currentOfferId?: string | null\n}) {\n const t = useT()\n const [query, setQuery] = React.useState('')\n const [results, setResults] = React.useState<ProductSearchResult[]>([])\n const [isLoading, setLoading] = React.useState(false)\n const [hasTyped, setHasTyped] = React.useState(false)\n\n const trimmed = query.trim()\n const shouldSearch = trimmed.length >= 2 || UUID_REGEX.test(trimmed)\n\n React.useEffect(() => {\n if (!shouldSearch) {\n setResults([])\n return\n }\n let cancelled = false\n const controller = new AbortController()\n const timeout = setTimeout(async () => {\n setLoading(true)\n try {\n const params = new URLSearchParams({ pageSize: '10' })\n if (UUID_REGEX.test(trimmed)) {\n params.set('id', trimmed)\n } else if (trimmed.length) {\n params.set('search', trimmed)\n }\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/products?${params.toString()}`,\n { signal: controller.signal },\n { fallback: { items: [] } },\n )\n const items = Array.isArray(payload.items) ? payload.items : []\n if (!cancelled) {\n const mapped = items.map((item) => mapProductSearchResult(item, channelId, currentOfferId))\n mapped.sort((a, b) => {\n const aBlocked = Boolean(a.existingOfferId && !a.isCurrentOfferProduct)\n const bBlocked = Boolean(b.existingOfferId && !b.isCurrentOfferProduct)\n return Number(aBlocked) - Number(bBlocked)\n })\n setResults(mapped)\n }\n } catch (err) {\n if ((err as Error).name === 'AbortError') return\n console.error('catalog.products.lookup', err)\n } finally {\n if (!cancelled) setLoading(false)\n }\n }, 250)\n return () => {\n cancelled = true\n clearTimeout(timeout)\n controller.abort()\n }\n }, [channelId, currentOfferId, shouldSearch, trimmed])\n\n const handleKeyDown = React.useCallback((event: React.KeyboardEvent<HTMLInputElement>) => {\n if (event.key === 'Enter' && UUID_REGEX.test(trimmed)) {\n event.preventDefault()\n onChange(trimmed)\n }\n }, [onChange, trimmed])\n\n const selectedHint = value\n ? t('sales.channels.offers.form.productSelectedHint', 'Selected product ID: {{id}}', { id: value })\n : null\n\n return (\n <div className=\"space-y-3\">\n <Input\n leftIcon={<Search />}\n value={query}\n onChange={(event) => {\n setQuery(event.target.value)\n setHasTyped(true)\n }}\n onKeyDown={handleKeyDown}\n placeholder={t('sales.channels.offers.form.productSearchPlaceholder', 'Search by title, SKU, or ID\u2026')}\n />\n {selectedHint ? (\n <div className=\"rounded border bg-muted px-3 py-2 text-xs text-muted-foreground\">\n {selectedHint}\n </div>\n ) : null}\n {value ? (\n <Button type=\"button\" variant=\"ghost\" size=\"sm\" onClick={() => onChange(null)}>\n {t('sales.channels.offers.form.productClear', 'Clear selection')}\n </Button>\n ) : null}\n {shouldSearch ? (\n <div className=\"space-y-2\">\n {isLoading ? (\n <div className=\"flex items-center gap-2 text-sm text-muted-foreground\">\n <Loader2 className=\"h-4 w-4 animate-spin\" />\n {t('sales.channels.offers.form.productSearchLoading', 'Searching products\u2026')}\n </div>\n ) : null}\n {!isLoading && !results.length ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchEmpty', 'No products match your search.')}\n </p>\n ) : null}\n <div className=\"space-y-2 max-h-80 overflow-y-auto\">\n {results.map((product) => {\n const isSelected = value === product.id\n const hasConflict = Boolean(product.existingOfferId && !product.isCurrentOfferProduct)\n return (\n <div\n key={product.id}\n className={cn(\n 'flex gap-3 rounded border bg-card p-3 transition-colors',\n isSelected ? 'border-primary/70 bg-primary/5' : 'hover:border-primary/50',\n )}\n >\n <div className=\"h-12 w-12 overflow-hidden rounded border bg-muted\">\n {product.defaultMediaUrl ? (\n <img src={product.defaultMediaUrl} alt={product.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex flex-1 flex-col gap-1\">\n <div className=\"flex items-center justify-between gap-2\">\n <div className=\"min-w-0\">\n <div className=\"truncate text-sm font-medium\">{product.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {product.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {product.sku}</div>\n ) : null}\n </div>\n <div className=\"text-xs font-medium text-muted-foreground\">\n {product.pricing ? formatPriceDisplay(product.pricing) : t('sales.channels.offers.form.productPriceMissing', 'No price')}\n </div>\n </div>\n {hasConflict ? (\n <div className=\"flex items-center justify-between gap-2 text-xs text-status-warning-text\">\n <span className=\"truncate\">\n {t('sales.channels.offers.form.productHasOffer', 'Already has an offer for this channel.')}\n </span>\n {channelId && product.existingOfferId ? (\n <Link\n href={`/backend/sales/channels/${encodeURIComponent(\n String(channelId)\n )}/offers/${encodeURIComponent(String(product.existingOfferId))}/edit`}\n className=\"shrink-0 font-medium text-primary hover:underline\"\n >\n {t('sales.channels.offers.form.productHasOfferLink', 'View offer')}\n </Link>\n ) : null}\n </div>\n ) : null}\n <div className=\"flex justify-end\">\n <Button\n type=\"button\"\n variant={isSelected ? 'secondary' : 'outline'}\n size=\"sm\"\n onClick={() => onChange(product.id)}\n disabled={hasConflict && !isSelected}\n >\n {hasConflict && !isSelected\n ? t('sales.channels.offers.form.productUnavailable', 'Unavailable')\n : isSelected\n ? t('sales.channels.offers.form.productSelected', 'Selected')\n : t('sales.channels.offers.form.productSelect', 'Select')}\n </Button>\n </div>\n </div>\n </div>\n )\n })}\n </div>\n </div>\n ) : hasTyped ? (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchHint', 'Type at least 2 characters or paste a product ID.')}\n </p>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSearchIntro', 'Search by name or paste the product id to find catalog items.')}\n </p>\n )}\n </div>\n )\n}\n\nfunction DefaultMediaSelect({\n value,\n options,\n onChange,\n productThumbnail,\n hasProduct,\n productDefaultMediaId,\n}: {\n value: string | null\n options: MediaOption[]\n onChange: (next: string | null) => void\n productThumbnail: string | null\n hasProduct: boolean\n productDefaultMediaId?: string | null\n}) {\n const t = useT()\n const filteredOptions = React.useMemo(() => {\n if (!productDefaultMediaId) return options\n return options.filter((opt) => opt.id !== productDefaultMediaId)\n }, [options, productDefaultMediaId])\n const hasAttachmentOptions = filteredOptions.length > 0\n const showPlaceholder = !hasAttachmentOptions && !productThumbnail && !hasProduct\n if (showPlaceholder) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.mediaSelectProduct', 'Select a product to load its media.')}\n </p>\n )\n }\n const tiles = [\n {\n id: 'inherit',\n label: t('sales.channels.offers.form.mediaInherit', 'Use product default'),\n thumbnail: productThumbnail,\n selected: value == null,\n onClick: () => onChange(null),\n },\n ...filteredOptions.map((opt) => ({\n id: opt.id,\n label: opt.label,\n thumbnail: opt.thumbnailUrl ?? null,\n selected: value === opt.id,\n onClick: () => onChange(opt.id),\n })),\n ]\n return (\n <div className=\"space-y-3\">\n <div className=\"text-xs text-muted-foreground\">\n <p>\n {t('sales.channels.offers.form.mediaHelp', 'Choose the thumbnail that should represent this offer in the channel.')}\n </p>\n {!hasAttachmentOptions && hasProduct ? (\n <p className=\"mt-1\">\n {t('sales.channels.offers.form.mediaEmpty', 'This product has no uploaded media yet; the product default will be used.')}\n </p>\n ) : null}\n </div>\n <div className=\"grid gap-3 sm:grid-cols-3\">\n {tiles.map((tile) => (\n <button\n key={tile.id}\n type=\"button\"\n className={cn(\n 'flex flex-col rounded border text-left transition-colors',\n tile.selected ? 'border-primary shadow-sm' : 'hover:border-primary/60',\n )}\n onClick={tile.onClick}\n >\n <div className=\"relative aspect-square overflow-hidden rounded-t bg-muted\">\n {tile.thumbnail ? (\n <img src={tile.thumbnail} alt={tile.label} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-6 w-6\" />\n </div>\n )}\n {tile.selected ? (\n <div className=\"absolute right-2 top-2 rounded-full bg-primary/90 px-2 py-0.5 text-xs font-semibold text-primary-foreground\">\n {t('sales.channels.offers.form.mediaSelected', 'Active')}\n </div>\n ) : null}\n </div>\n <div className=\"p-2\">\n <div className=\"line-clamp-2 text-xs font-medium\">{tile.label}</div>\n </div>\n </button>\n ))}\n </div>\n </div>\n )\n}\n\nfunction OfferFormWatchers({\n values,\n setValue,\n productCache,\n attachmentCache,\n setMediaOptions,\n setProductSummary,\n setVariantPreviews,\n variantCache,\n variantMediaCache,\n channelId,\n manualMediaSelections,\n setCurrentProductId,\n errors,\n}: CrudFormGroupComponentProps & {\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n setMediaOptions: React.Dispatch<React.SetStateAction<MediaOption[]>>\n setProductSummary: React.Dispatch<React.SetStateAction<ProductSummary>>\n setVariantPreviews: React.Dispatch<React.SetStateAction<ProductVariantPreview[]>>\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n channelId: string | null\n manualMediaSelections: React.MutableRefObject<Set<string>>\n setCurrentProductId: React.Dispatch<React.SetStateAction<string | null>>\n}) {\n const previousProductIdRef = React.useRef<string | null>(null)\n const initializedProductRef = React.useRef(false)\n React.useEffect(() => {\n const productId = typeof values.productId === 'string' ? values.productId : null\n setCurrentProductId(productId)\n if (!productId) {\n setMediaOptions([])\n setProductSummary(null)\n setVariantPreviews([])\n previousProductIdRef.current = null\n return\n }\n const resolvedProductId = productId as string\n const resolvedChannelId = channelId ?? null\n if (!initializedProductRef.current) {\n previousProductIdRef.current = resolvedProductId\n initializedProductRef.current = true\n } else if (previousProductIdRef.current !== resolvedProductId) {\n previousProductIdRef.current = resolvedProductId\n setValue('defaultMediaId', undefined)\n }\n let cancelled = false\n async function load() {\n try {\n const summary = await resolveProductSummaryWithCache({\n productId: resolvedProductId,\n channelId: resolvedChannelId,\n productCache,\n })\n if (!cancelled) {\n setProductSummary(summary ?? null)\n if (summary) {\n const hasTitle = typeof values.title === 'string' && values.title.trim().length > 0\n if (!hasTitle && summary.title) {\n setValue('title', summary.title)\n }\n const hasDescription =\n typeof values.description === 'string' && values.description.trim().length > 0\n if (!hasDescription && summary.description) {\n setValue('description', summary.description)\n }\n if (\n !values.defaultMediaId &&\n summary.defaultMediaId &&\n !manualMediaSelections.current.has(resolvedProductId)\n ) {\n setValue('defaultMediaId', summary.defaultMediaId)\n }\n }\n }\n const attachments = await resolveProductMediaOptionsWithCache({\n productId: resolvedProductId,\n attachmentCache,\n })\n if (!cancelled) {\n const variants = await resolveVariantPreviewsWithCache({\n productId: resolvedProductId,\n variantCache,\n variantMediaCache,\n })\n const mergedMedia = buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n })\n attachmentCache.current.set(resolvedProductId, mergedMedia)\n setMediaOptions(mergedMedia)\n setVariantPreviews(variants)\n }\n } catch (err) {\n console.error('sales.channels.offer.watchers', err)\n }\n }\n void load()\n return () => { cancelled = true }\n }, [\n attachmentCache,\n channelId,\n manualMediaSelections,\n productCache,\n setMediaOptions,\n setProductSummary,\n setValue,\n setVariantPreviews,\n values.defaultMediaId,\n values.description,\n values.productId,\n values.title,\n variantCache,\n variantMediaCache,\n setCurrentProductId,\n ])\n return null\n}\n\nasync function resolveProductSummaryWithCache({\n productId,\n channelId,\n productCache,\n}: {\n productId: string\n channelId: string | null\n productCache: React.MutableRefObject<Map<string, ProductSummaryCacheEntry>>\n}): Promise<ProductSummaryCacheEntry | null> {\n if (!productId) return null\n const cacheKey = channelId ? `${productId}:${channelId}` : productId\n let summary: ProductSummaryCacheEntry | null | undefined = productCache.current.get(cacheKey)\n if (summary) return summary\n const params = new URLSearchParams({ id: productId, pageSize: '1' })\n if (channelId) params.set('channelId', channelId)\n const payload = await readApiResultOrThrow<OfferResponse>(\n `/api/catalog/products?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n const product = Array.isArray(payload.items) ? payload.items[0] : null\n summary = product ? mapProductSummary(product) : null\n if (summary) {\n productCache.current.set(cacheKey, summary)\n }\n return summary ?? null\n}\n\nasync function resolveProductMediaOptionsWithCache({\n productId,\n attachmentCache,\n}: {\n productId: string\n attachmentCache: React.MutableRefObject<Map<string, MediaOption[]>>\n}): Promise<MediaOption[]> {\n if (!productId) return []\n const cached = attachmentCache.current.get(productId) ?? []\n if (cached.length) {\n const deduped = dedupeMediaOptions(cached)\n attachmentCache.current.set(productId, deduped)\n return deduped\n }\n const attachments = dedupeMediaOptions(await loadProductMedia(productId))\n attachmentCache.current.set(productId, attachments)\n return attachments\n}\n\nasync function resolveVariantPreviewsWithCache({\n productId,\n variantCache,\n variantMediaCache,\n}: {\n productId: string\n variantCache: React.MutableRefObject<Map<string, ProductVariantPreview[]>>\n variantMediaCache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>\n}): Promise<ProductVariantPreview[]> {\n if (!productId) return []\n const cached = variantCache.current.get(productId)\n if (cached) return cached\n const variantPayload = await readApiResultOrThrow<{ items?: Array<Record<string, unknown>> }>(\n `/api/catalog/variants?productId=${encodeURIComponent(productId)}&pageSize=${MAX_LIST_PAGE_SIZE}`,\n undefined,\n { fallback: { items: [] } },\n )\n const items = Array.isArray(variantPayload.items) ? variantPayload.items : []\n const variants = await Promise.all(\n items.map(async (item) => {\n const preview = mapVariantPreview(item)\n const media = await resolveVariantThumbnail(preview.id, variantMediaCache)\n return {\n ...preview,\n thumbnailId: media?.attachmentId ?? preview.thumbnailId,\n thumbnailUrl: media?.thumbnailUrl ?? preview.thumbnailUrl,\n thumbnailFileName: media?.fileName ?? preview.thumbnailFileName,\n }\n }),\n )\n variantCache.current.set(productId, variants)\n return variants\n}\n\nfunction mapProductSummary(item: Record<string, unknown>): ProductSummaryCacheEntry {\n const pricingSource = item.pricing && typeof item.pricing === 'object' ? item.pricing as Record<string, unknown> : null\n return {\n title: typeof item.title === 'string' ? item.title : '',\n description: typeof item.description === 'string' ? item.description : null,\n defaultMediaId: typeof item.defaultMediaId === 'string'\n ? item.defaultMediaId\n : typeof item.default_media_id === 'string'\n ? item.default_media_id\n : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n sku: typeof item.sku === 'string' ? item.sku : null,\n pricing: normalizePricing(pricingSource),\n }\n}\n\nfunction normalizePricing(source: Record<string, unknown> | null): PricingSummary | null {\n if (!source) return null\n const currencyCode = typeof source.currencyCode === 'string'\n ? source.currencyCode\n : typeof source.currency_code === 'string'\n ? source.currency_code\n : null\n const unitPriceNet = typeof source.unitPriceNet === 'string'\n ? source.unitPriceNet\n : typeof source.unit_price_net === 'string'\n ? source.unit_price_net\n : null\n const unitPriceGross = typeof source.unitPriceGross === 'string'\n ? source.unitPriceGross\n : typeof source.unit_price_gross === 'string'\n ? source.unit_price_gross\n : null\n const displayMode = source.displayMode === 'including-tax' || source.display_mode === 'including-tax'\n ? 'including-tax'\n : source.displayMode === 'excluding-tax' || source.display_mode === 'excluding-tax'\n ? 'excluding-tax'\n : null\n return { currencyCode, unitPriceNet, unitPriceGross, displayMode }\n}\n\nasync function loadProductMedia(productId: string): Promise<MediaOption[]> {\n if (!productId) return []\n const normalize = (items: Array<{ id?: string; fileName?: string; thumbnailUrl?: string | null }>) => (\n items\n .filter((item): item is { id: string; fileName: string; thumbnailUrl?: string | null } => (\n typeof item.id === 'string' && typeof item.fileName === 'string'\n ))\n .map((item) => ({\n id: item.id,\n label: item.fileName,\n fileName: item.fileName,\n thumbnailUrl: typeof item.thumbnailUrl === 'string'\n ? item.thumbnailUrl\n : buildAttachmentImageUrl(item.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(item.fileName),\n }),\n }))\n )\n try {\n const primary = await apiCall<AttachmentsResponse>(\n `/api/catalog/product-media?productId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (primary.ok && primary.result?.items) {\n return normalize(primary.result.items)\n }\n } catch (err) {\n console.error('catalog.product-media.lookup', err)\n }\n try {\n const fallback = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product)}&recordId=${encodeURIComponent(productId)}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (fallback.ok && fallback.result?.items) {\n return normalize(fallback.result.items)\n }\n } catch (err) {\n console.error('attachments.lookup', err)\n }\n return []\n}\n\nfunction buildVariantMediaOptions(variants: ProductVariantPreview[]): MediaOption[] {\n return variants\n .map((variant): MediaOption | null => {\n if (!variant.thumbnailId || !variant.thumbnailUrl) return null\n const label = variant.name || variant.sku || 'Variant'\n const fileName = variant.thumbnailFileName ?? `${variant.thumbnailId}.jpg`\n return {\n id: variant.thumbnailId,\n label,\n fileName,\n thumbnailUrl: variant.thumbnailUrl,\n }\n })\n .filter((entry): entry is MediaOption => Boolean(entry))\n}\n\nfunction buildMediaOptionsFromSources({\n attachments,\n variants,\n summary,\n}: {\n attachments?: MediaOption[] | null\n variants?: ProductVariantPreview[] | null\n summary?: ProductSummary | null\n}): MediaOption[] {\n const merged = dedupeMediaOptions([\n ...(attachments ?? []),\n ...buildVariantMediaOptions(variants ?? []),\n ])\n const defaultId = summary?.defaultMediaId ?? null\n const defaultUrl = summary?.defaultMediaUrl ?? null\n if (defaultId && defaultUrl && !merged.some((entry) => entry.id === defaultId)) {\n const fileName = inferFileNameFromUrl(defaultUrl, defaultId)\n merged.unshift({\n id: defaultId,\n label: fileName,\n fileName,\n thumbnailUrl: defaultUrl,\n })\n }\n return merged\n}\n\nfunction dedupeMediaOptions(entries: MediaOption[] | null | undefined): MediaOption[] {\n if (!Array.isArray(entries)) return []\n const seen = new Set<string>()\n const result: MediaOption[] = []\n for (const entry of entries) {\n if (!entry || typeof entry.id !== 'string') continue\n if (seen.has(entry.id)) continue\n seen.add(entry.id)\n result.push(entry)\n }\n return result\n}\n\nfunction inferFileNameFromUrl(url: string | null, fallbackId: string): string {\n if (typeof url === 'string' && url.length) {\n const cleaned = url.split(/[?#]/)[0]\n const last = cleaned.split('/').pop()\n if (last && last.trim().length) return last\n }\n return `${fallbackId}.jpg`\n}\n\nfunction mapVariantPreview(item: Record<string, unknown>): ProductVariantPreview {\n return {\n id: typeof item.id === 'string' ? item.id : '',\n name: typeof item.name === 'string'\n ? item.name\n : typeof item.sku === 'string'\n ? item.sku\n : 'Variant',\n sku: typeof item.sku === 'string' ? item.sku : null,\n thumbnailUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n thumbnailId: null,\n thumbnailFileName: null,\n }\n}\n\nasync function resolveVariantThumbnail(\n variantId: string,\n cache: React.MutableRefObject<Map<string, VariantThumbnailInfo>>,\n): Promise<VariantThumbnailInfo | null> {\n if (!variantId) return null\n if (cache.current.has(variantId)) {\n return cache.current.get(variantId) ?? null\n }\n try {\n const payload = await apiCall<AttachmentsResponse>(\n `/api/attachments?entityId=${encodeURIComponent(E.catalog.catalog_product_variant)}&recordId=${encodeURIComponent(variantId)}`,\n )\n const items = payload.ok && payload.result?.items ? payload.result.items : []\n const first = items.find((item) => typeof item.id === 'string')\n if (first?.id) {\n const thumbnailUrl = typeof first.thumbnailUrl === 'string'\n ? first.thumbnailUrl\n : buildAttachmentImageUrl(first.id, {\n width: 360,\n height: 360,\n slug: slugifyAttachmentFileName(first.fileName ?? first.id),\n })\n const info: VariantThumbnailInfo = {\n attachmentId: first.id,\n thumbnailUrl: thumbnailUrl ?? null,\n fileName: typeof first.fileName === 'string' ? first.fileName : null,\n }\n cache.current.set(variantId, info)\n return info\n }\n } catch (err) {\n console.error('sales.channels.offer.variantMedia', err)\n }\n const empty: VariantThumbnailInfo = { attachmentId: null, thumbnailUrl: null, fileName: null }\n cache.current.set(variantId, empty)\n return empty\n}\n\nfunction mapProductSearchResult(\n item: Record<string, unknown>,\n channelId?: string | null,\n currentOfferId?: string | null,\n): ProductSearchResult {\n const offers = Array.isArray((item as { offers?: unknown }).offers)\n ? (item as { offers: Array<Record<string, unknown>> }).offers\n : []\n const channelOffer = offers.find((entry) => {\n if (!entry || typeof entry !== 'object') return false\n const offerChannelId = typeof entry.channelId === 'string'\n ? entry.channelId\n : typeof (entry as Record<string, unknown>).channel_id === 'string'\n ? (entry as Record<string, unknown>).channel_id\n : null\n return channelId ? offerChannelId === channelId : false\n }) ?? null\n const existingOfferId = channelOffer && typeof channelOffer.id === 'string' ? channelOffer.id : null\n return {\n id: typeof item.id === 'string' ? item.id : '',\n title: typeof item.title === 'string' ? item.title : '',\n sku: typeof item.sku === 'string' ? item.sku : null,\n defaultMediaUrl: typeof item.defaultMediaUrl === 'string'\n ? item.defaultMediaUrl\n : typeof item.default_media_url === 'string'\n ? item.default_media_url\n : null,\n pricing: item.pricing && typeof item.pricing === 'object'\n ? normalizePricing(item.pricing as Record<string, unknown>)\n : null,\n existingOfferId,\n existingOfferTitle:\n channelOffer && typeof channelOffer.title === 'string' ? channelOffer.title : null,\n isCurrentOfferProduct: Boolean(existingOfferId && currentOfferId && existingOfferId === currentOfferId),\n }\n}\n\nfunction formatPriceDisplay(pricing: PricingSummary | null): string {\n if (!pricing) return '\u2014'\n const amount = pricing.displayMode === 'including-tax'\n ? pricing.unitPriceGross ?? pricing.unitPriceNet\n : pricing.unitPriceNet ?? pricing.unitPriceGross\n if (!amount) return pricing.currencyCode ?? '\u2014'\n return `${pricing.currencyCode ?? ''} ${amount}`\n}\n\nfunction PriceOverridesEditor({\n values,\n onChange,\n priceKinds,\n basePrice,\n onRemoveDraft,\n}: {\n values: PriceOverrideDraft[]\n onChange: (next: PriceOverrideDraft[]) => void\n priceKinds: PriceKindSummary[]\n basePrice: PricingSummary | null\n onRemoveDraft?: (draft: PriceOverrideDraft) => Promise<boolean> | boolean\n}) {\n const t = useT()\n const baseAmount = React.useMemo(() => {\n if (!basePrice) return ''\n const net = basePrice.unitPriceNet ?? null\n const gross = basePrice.unitPriceGross ?? null\n if (basePrice.displayMode === 'including-tax') {\n return gross ?? net ?? ''\n }\n if (basePrice.displayMode === 'excluding-tax') {\n return net ?? gross ?? ''\n }\n return net ?? gross ?? ''\n }, [basePrice])\n const baseDefaults = React.useMemo(() => ({\n amount: baseAmount,\n currencyCode: basePrice?.currencyCode ?? null,\n displayMode: basePrice?.displayMode ?? null,\n }), [baseAmount, basePrice?.currencyCode, basePrice?.displayMode])\n const usedKindIdSet = React.useMemo(() => {\n const next = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n next.add(row.priceKindId)\n }\n })\n return next\n }, [values])\n const availableKindCount = priceKinds.reduce(\n (count, kind) => (usedKindIdSet.has(kind.id) ? count : count + 1),\n 0,\n )\n const canAddRow = availableKindCount > 0\n const addRow = React.useCallback(() => {\n const usedIds = new Set<string>()\n values.forEach((row) => {\n if (typeof row.priceKindId === 'string' && row.priceKindId.length) {\n usedIds.add(row.priceKindId)\n }\n })\n const nextKind = priceKinds.find((kind) => !usedIds.has(kind.id))\n if (!nextKind && priceKinds.length) {\n return\n }\n onChange([\n ...values,\n {\n tempId: crypto.randomUUID?.() ?? Math.random().toString(36).slice(2),\n amount: baseDefaults.amount,\n currencyCode: nextKind?.currencyCode ?? baseDefaults.currencyCode,\n displayMode: nextKind?.displayMode ?? baseDefaults.displayMode,\n priceKindId: nextKind?.id ?? null,\n priceKindCode: nextKind?.code ?? nextKind?.title ?? null,\n },\n ])\n }, [baseDefaults, onChange, priceKinds, values])\n\n const updateRow = React.useCallback((tempId: string, patch: Partial<PriceOverrideDraft>) => {\n onChange(values.map((row) => (row.tempId === tempId ? { ...row, ...patch } : row)))\n }, [onChange, values])\n\n const removeRow = React.useCallback(async (row: PriceOverrideDraft) => {\n const allowRemoval = await onRemoveDraft?.(row)\n if (allowRemoval === false) return\n onChange(values.filter((entry) => entry.tempId !== row.tempId))\n }, [onChange, onRemoveDraft, values])\n\n return (\n <div className=\"space-y-4\">\n <div className=\"rounded border bg-muted/50 px-3 py-2\">\n <div className=\"text-xs uppercase text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceLabel', 'Original product price')}\n </div>\n <div className=\"text-base font-semibold\">\n {basePrice ? formatPriceDisplay(basePrice) : t('sales.channels.offers.pricing.basePriceMissing', 'No price found')}\n </div>\n <div className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.basePriceHelp', 'Shown to shoppers when no override is configured.')}\n </div>\n </div>\n <div className=\"space-y-2\">\n <div className=\"flex items-center justify-between\">\n <p className=\"text-sm text-muted-foreground\">\n {t('sales.channels.offers.pricing.help', 'Provide overrides for price kinds when this offer is active.')}\n </p>\n <Button type=\"button\" variant=\"outline\" size=\"sm\" onClick={addRow} disabled={!canAddRow}>\n {t('sales.channels.offers.pricing.add', 'Add price')}\n </Button>\n </div>\n {!canAddRow ? (\n <p className=\"text-xs text-muted-foreground\">\n {priceKinds.length\n ? t('sales.channels.offers.pricing.allKindsUsed', 'Each price kind already has an override.')\n : t('sales.channels.offers.pricing.noKindsAvailable', 'Define a price kind before adding overrides.')}\n </p>\n ) : null}\n </div>\n <div className=\"flex items-center justify-between\">\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.overrideHint', 'Overrides take precedence over the original product price.')}\n </p>\n </div>\n {values.length ? (\n <div className=\"space-y-2\">\n {values.map((row) => (\n <div key={row.tempId} className=\"grid gap-2 rounded border p-3 md:grid-cols-3\">\n <Select\n value={row.priceKindId || undefined}\n onValueChange={(value) => {\n const next = priceKinds.find((kind) => kind.id === value)\n updateRow(row.tempId, {\n priceKindId: next?.id ?? null,\n priceKindCode: next?.code ?? next?.title ?? null,\n currencyCode: next?.currencyCode ?? null,\n displayMode: next?.displayMode ?? null,\n })\n }}\n >\n <SelectTrigger>\n <SelectValue placeholder={t('sales.channels.offers.pricing.selectKind', 'Select price kind')} />\n </SelectTrigger>\n <SelectContent>\n {priceKinds.map((kind) => (\n <SelectItem\n key={kind.id}\n value={kind.id}\n disabled={usedKindIdSet.has(kind.id) && row.priceKindId !== kind.id}\n >\n {kind.title ?? kind.code ?? kind.id}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <div className=\"relative\">\n {(row.currencyCode ?? basePrice?.currencyCode) ? (\n <span className=\"pointer-events-none absolute left-3 top-1/2 -translate-y-1/2 text-xs font-semibold text-muted-foreground\">\n {row.currencyCode ?? basePrice?.currencyCode}\n </span>\n ) : null}\n <Input\n inputClassName={cn(row.currencyCode || basePrice?.currencyCode ? 'pl-13' : '')}\n type=\"number\"\n placeholder={t('sales.channels.offers.pricing.amount', 'Amount')}\n value={row.amount ?? ''}\n onChange={(event) => updateRow(row.tempId, { amount: event.target.value })}\n />\n </div>\n <div className=\"flex flex-col justify-between gap-2 text-xs text-muted-foreground sm:flex-row sm:items-center\">\n <span>\n {row.displayMode === 'including-tax'\n ? t('sales.channels.offers.pricing.includingTax', 'Including tax')\n : t('sales.channels.offers.pricing.excludingTax', 'Excluding tax')}\n </span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"gap-1 px-2 font-normal text-destructive hover:text-destructive focus-visible:text-destructive\"\n onClick={() => { void removeRow(row) }}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n {t('sales.channels.offers.pricing.remove', 'Remove')}\n </Button>\n </div>\n </div>\n ))}\n </div>\n ) : (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.pricing.empty', 'No overrides yet.')}\n {basePrice ? (\n <>\n {' '}\n {t(\n 'sales.channels.offers.pricing.emptyFallback',\n 'Using {price} from the product until you add overrides.',\n { price: formatPriceDisplay(basePrice) },\n )}\n </>\n ) : null}\n </p>\n )}\n </div>\n )\n}\n\nfunction ProductOverviewCard({ summary, variants }: { summary: ProductSummary; variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!summary) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.productSummaryPlaceholder', 'Select a product to preview its media, price, and variants.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-4\">\n <div className=\"flex gap-3\">\n <div className=\"h-16 w-16 overflow-hidden rounded border bg-muted\">\n {summary.defaultMediaUrl ? (\n <img src={summary.defaultMediaUrl} alt={summary.title} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-5 w-5\" />\n </div>\n )}\n </div>\n <div className=\"flex-1\">\n <div className=\"text-sm font-semibold\">{summary.title || t('sales.channels.offers.form.productUntitled', 'Untitled product')}</div>\n {summary.sku ? (\n <div className=\"text-xs text-muted-foreground\">SKU \u00B7 {summary.sku}</div>\n ) : null}\n <div className=\"text-sm\">\n <span className=\"text-muted-foreground\">{t('sales.channels.offers.form.productPriceLabel', 'Base price')}:</span>{' '}\n <span className=\"font-semibold\">{formatPriceDisplay(summary.pricing)}</span>\n </div>\n </div>\n </div>\n {summary.description ? (\n <p className=\"text-sm text-muted-foreground\">{summary.description}</p>\n ) : null}\n <ProductVariantsList variants={variants} />\n </div>\n )\n}\n\nfunction ProductVariantsList({ variants }: { variants: ProductVariantPreview[] }) {\n const t = useT()\n if (!variants.length) {\n return (\n <p className=\"text-xs text-muted-foreground\">\n {t('sales.channels.offers.form.variantsEmpty', 'No variants available for this product.')}\n </p>\n )\n }\n return (\n <div className=\"space-y-2\">\n <div className=\"text-sm font-medium\">{t('sales.channels.offers.form.variantsTitle', 'Variants')}</div>\n <div className=\"space-y-2 max-h-64 overflow-y-auto pr-1\">\n {variants.map((variant) => (\n <div key={variant.id} className=\"flex gap-3 rounded border bg-card p-2\">\n <div className=\"h-10 w-10 overflow-hidden rounded border bg-muted\">\n {variant.thumbnailUrl ? (\n <img src={variant.thumbnailUrl} alt={variant.name} className=\"h-full w-full object-cover\" />\n ) : (\n <div className=\"flex h-full items-center justify-center text-muted-foreground\">\n <ImageIcon className=\"h-4 w-4\" />\n </div>\n )}\n </div>\n <div className=\"min-w-0\">\n <div className=\"text-xs font-medium\">{variant.name}</div>\n {variant.sku ? (\n <div className=\"text-overline text-muted-foreground\">SKU \u00B7 {variant.sku}</div>\n ) : null}\n </div>\n </div>\n ))}\n </div>\n </div>\n )\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -8,7 +8,8 @@ import { RowActions } from "@open-mercato/ui/backend/RowActions";
8
8
  import { Button } from "@open-mercato/ui/primitives/button";
9
9
  import { BooleanIcon } from "@open-mercato/ui/backend/ValueIcons";
10
10
  import { flash } from "@open-mercato/ui/backend/FlashMessages";
11
- import { readApiResultOrThrow } from "@open-mercato/ui/backend/utils/apiCall";
11
+ import { readApiResultOrThrow, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
12
+ import { buildOptimisticLockHeader } from "@open-mercato/ui/backend/utils/optimisticLock";
12
13
  import { deleteCrud } from "@open-mercato/ui/backend/utils/crud";
13
14
  import { useT } from "@open-mercato/shared/lib/i18n/context";
14
15
  import { mapOfferRow, renderOfferPriceSummary } from "./offerTableUtils.js";
@@ -98,9 +99,12 @@ function SalesChannelOffersPanel({ channelId, channelName }) {
98
99
  }, [loadOffers, reloadToken]);
99
100
  const handleDelete = React.useCallback(async (row) => {
100
101
  try {
101
- await deleteCrud("catalog/offers", row.id, {
102
- errorMessage: t("sales.channels.offers.errors.delete", "Failed to delete offer.")
103
- });
102
+ await withScopedApiRequestHeaders(
103
+ buildOptimisticLockHeader(row.updatedAt),
104
+ () => deleteCrud("catalog/offers", row.id, {
105
+ errorMessage: t("sales.channels.offers.errors.delete", "Failed to delete offer.")
106
+ })
107
+ );
104
108
  flash(t("sales.channels.offers.messages.deleted", "Offer deleted."), "success");
105
109
  setReloadToken((token) => token + 1);
106
110
  } catch (err) {