@open-mercato/core 0.6.8-develop.6925.1.cefa200fa4 → 0.6.8-develop.6931.1.4a1e1c786b

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 (405) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/eudr_due_diligence_statement/index.js +47 -0
  3. package/dist/generated/entities/eudr_due_diligence_statement/index.js.map +7 -0
  4. package/dist/generated/entities/eudr_evidence_submission/index.js +51 -0
  5. package/dist/generated/entities/eudr_evidence_submission/index.js.map +7 -0
  6. package/dist/generated/entities/eudr_mitigation_action/index.js +31 -0
  7. package/dist/generated/entities/eudr_mitigation_action/index.js.map +7 -0
  8. package/dist/generated/entities/eudr_plot/index.js +39 -0
  9. package/dist/generated/entities/eudr_plot/index.js.map +7 -0
  10. package/dist/generated/entities/eudr_product_mapping/index.js +31 -0
  11. package/dist/generated/entities/eudr_product_mapping/index.js.map +7 -0
  12. package/dist/generated/entities/eudr_risk_assessment/index.js +35 -0
  13. package/dist/generated/entities/eudr_risk_assessment/index.js.map +7 -0
  14. package/dist/generated/entities.ids.generated.js +9 -0
  15. package/dist/generated/entities.ids.generated.js.map +2 -2
  16. package/dist/generated/entity-fields-registry.js +120 -0
  17. package/dist/generated/entity-fields-registry.js.map +2 -2
  18. package/dist/helpers/integration/ui.js +3 -0
  19. package/dist/helpers/integration/ui.js.map +2 -2
  20. package/dist/modules/attachments/fields/attachment.js +5 -1
  21. package/dist/modules/attachments/fields/attachment.js.map +2 -2
  22. package/dist/modules/attachments/lib/crud.js +3 -1
  23. package/dist/modules/attachments/lib/crud.js.map +2 -2
  24. package/dist/modules/eudr/acl.js +43 -0
  25. package/dist/modules/eudr/acl.js.map +7 -0
  26. package/dist/modules/eudr/ai-agents.js +205 -0
  27. package/dist/modules/eudr/ai-agents.js.map +7 -0
  28. package/dist/modules/eudr/ai-tools/compliance-pack.js +495 -0
  29. package/dist/modules/eudr/ai-tools/compliance-pack.js.map +7 -0
  30. package/dist/modules/eudr/ai-tools/types.js +10 -0
  31. package/dist/modules/eudr/ai-tools/types.js.map +7 -0
  32. package/dist/modules/eudr/ai-tools.js +10 -0
  33. package/dist/modules/eudr/ai-tools.js.map +7 -0
  34. package/dist/modules/eudr/api/dashboard/widgets/compliance-overview/route.js +386 -0
  35. package/dist/modules/eudr/api/dashboard/widgets/compliance-overview/route.js.map +7 -0
  36. package/dist/modules/eudr/api/evidence-submissions/route.js +318 -0
  37. package/dist/modules/eudr/api/evidence-submissions/route.js.map +7 -0
  38. package/dist/modules/eudr/api/mitigation-actions/route.js +249 -0
  39. package/dist/modules/eudr/api/mitigation-actions/route.js.map +7 -0
  40. package/dist/modules/eudr/api/openapi.js +27 -0
  41. package/dist/modules/eudr/api/openapi.js.map +7 -0
  42. package/dist/modules/eudr/api/plots/import/route.js +294 -0
  43. package/dist/modules/eudr/api/plots/import/route.js.map +7 -0
  44. package/dist/modules/eudr/api/plots/route.js +279 -0
  45. package/dist/modules/eudr/api/plots/route.js.map +7 -0
  46. package/dist/modules/eudr/api/product-mappings/route.js +257 -0
  47. package/dist/modules/eudr/api/product-mappings/route.js.map +7 -0
  48. package/dist/modules/eudr/api/product-mappings/suggestions/apply/route.js +298 -0
  49. package/dist/modules/eudr/api/product-mappings/suggestions/apply/route.js.map +7 -0
  50. package/dist/modules/eudr/api/product-mappings/suggestions/route.js +132 -0
  51. package/dist/modules/eudr/api/product-mappings/suggestions/route.js.map +7 -0
  52. package/dist/modules/eudr/api/reports/annual/route.js +266 -0
  53. package/dist/modules/eudr/api/reports/annual/route.js.map +7 -0
  54. package/dist/modules/eudr/api/risk-assessments/route.js +300 -0
  55. package/dist/modules/eudr/api/risk-assessments/route.js.map +7 -0
  56. package/dist/modules/eudr/api/statements/[id]/export/route.js +631 -0
  57. package/dist/modules/eudr/api/statements/[id]/export/route.js.map +7 -0
  58. package/dist/modules/eudr/api/statements/[id]/readiness/route.js +111 -0
  59. package/dist/modules/eudr/api/statements/[id]/readiness/route.js.map +7 -0
  60. package/dist/modules/eudr/api/statements/route.js +314 -0
  61. package/dist/modules/eudr/api/statements/route.js.map +7 -0
  62. package/dist/modules/eudr/api/suppliers/compliance/route.js +173 -0
  63. package/dist/modules/eudr/api/suppliers/compliance/route.js.map +7 -0
  64. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.js +468 -0
  65. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.js.map +7 -0
  66. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js +16 -0
  67. package/dist/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.js.map +7 -0
  68. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.js +351 -0
  69. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.js.map +7 -0
  70. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js +17 -0
  71. package/dist/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.js.map +7 -0
  72. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js +313 -0
  73. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.js.map +7 -0
  74. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js +16 -0
  75. package/dist/modules/eudr/backend/eudr/evidence-submissions/page.meta.js.map +7 -0
  76. package/dist/modules/eudr/backend/eudr/page.js +360 -0
  77. package/dist/modules/eudr/backend/eudr/page.js.map +7 -0
  78. package/dist/modules/eudr/backend/eudr/page.meta.js +16 -0
  79. package/dist/modules/eudr/backend/eudr/page.meta.js.map +7 -0
  80. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js +346 -0
  81. package/dist/modules/eudr/backend/eudr/plots/[id]/page.js.map +7 -0
  82. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js +16 -0
  83. package/dist/modules/eudr/backend/eudr/plots/[id]/page.meta.js.map +7 -0
  84. package/dist/modules/eudr/backend/eudr/plots/create/page.js +253 -0
  85. package/dist/modules/eudr/backend/eudr/plots/create/page.js.map +7 -0
  86. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js +17 -0
  87. package/dist/modules/eudr/backend/eudr/plots/create/page.meta.js.map +7 -0
  88. package/dist/modules/eudr/backend/eudr/plots/page.js +386 -0
  89. package/dist/modules/eudr/backend/eudr/plots/page.js.map +7 -0
  90. package/dist/modules/eudr/backend/eudr/plots/page.meta.js +16 -0
  91. package/dist/modules/eudr/backend/eudr/plots/page.meta.js.map +7 -0
  92. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.js +253 -0
  93. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.js.map +7 -0
  94. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js +16 -0
  95. package/dist/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.js.map +7 -0
  96. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.js +174 -0
  97. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.js.map +7 -0
  98. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js +17 -0
  99. package/dist/modules/eudr/backend/eudr/product-mappings/create/page.meta.js.map +7 -0
  100. package/dist/modules/eudr/backend/eudr/product-mappings/page.js +306 -0
  101. package/dist/modules/eudr/backend/eudr/product-mappings/page.js.map +7 -0
  102. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js +16 -0
  103. package/dist/modules/eudr/backend/eudr/product-mappings/page.meta.js.map +7 -0
  104. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.js +335 -0
  105. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.js.map +7 -0
  106. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js +16 -0
  107. package/dist/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.js.map +7 -0
  108. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.js +220 -0
  109. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.js.map +7 -0
  110. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js +17 -0
  111. package/dist/modules/eudr/backend/eudr/risk-assessments/create/page.meta.js.map +7 -0
  112. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js +324 -0
  113. package/dist/modules/eudr/backend/eudr/risk-assessments/page.js.map +7 -0
  114. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js +16 -0
  115. package/dist/modules/eudr/backend/eudr/risk-assessments/page.meta.js.map +7 -0
  116. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js +648 -0
  117. package/dist/modules/eudr/backend/eudr/statements/[id]/page.js.map +7 -0
  118. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js +16 -0
  119. package/dist/modules/eudr/backend/eudr/statements/[id]/page.meta.js.map +7 -0
  120. package/dist/modules/eudr/backend/eudr/statements/create/page.js +432 -0
  121. package/dist/modules/eudr/backend/eudr/statements/create/page.js.map +7 -0
  122. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js +17 -0
  123. package/dist/modules/eudr/backend/eudr/statements/create/page.meta.js.map +7 -0
  124. package/dist/modules/eudr/backend/eudr/statements/page.js +309 -0
  125. package/dist/modules/eudr/backend/eudr/statements/page.js.map +7 -0
  126. package/dist/modules/eudr/backend/eudr/statements/page.meta.js +16 -0
  127. package/dist/modules/eudr/backend/eudr/statements/page.meta.js.map +7 -0
  128. package/dist/modules/eudr/ce.js +56 -0
  129. package/dist/modules/eudr/ce.js.map +7 -0
  130. package/dist/modules/eudr/commands/evidence-submissions.js +571 -0
  131. package/dist/modules/eudr/commands/evidence-submissions.js.map +7 -0
  132. package/dist/modules/eudr/commands/index.js +7 -0
  133. package/dist/modules/eudr/commands/index.js.map +7 -0
  134. package/dist/modules/eudr/commands/lifecycle-events.js +19 -0
  135. package/dist/modules/eudr/commands/lifecycle-events.js.map +7 -0
  136. package/dist/modules/eudr/commands/mitigation-actions.js +488 -0
  137. package/dist/modules/eudr/commands/mitigation-actions.js.map +7 -0
  138. package/dist/modules/eudr/commands/plots.js +517 -0
  139. package/dist/modules/eudr/commands/plots.js.map +7 -0
  140. package/dist/modules/eudr/commands/product-mappings.js +468 -0
  141. package/dist/modules/eudr/commands/product-mappings.js.map +7 -0
  142. package/dist/modules/eudr/commands/risk-assessments.js +599 -0
  143. package/dist/modules/eudr/commands/risk-assessments.js.map +7 -0
  144. package/dist/modules/eudr/commands/statements.js +747 -0
  145. package/dist/modules/eudr/commands/statements.js.map +7 -0
  146. package/dist/modules/eudr/components/CountrySelectField.js +64 -0
  147. package/dist/modules/eudr/components/CountrySelectField.js.map +7 -0
  148. package/dist/modules/eudr/components/GeometryInput.js +133 -0
  149. package/dist/modules/eudr/components/GeometryInput.js.map +7 -0
  150. package/dist/modules/eudr/components/MappingSuggestionsDialog.js +307 -0
  151. package/dist/modules/eudr/components/MappingSuggestionsDialog.js.map +7 -0
  152. package/dist/modules/eudr/components/MitigationActionsSection.js +345 -0
  153. package/dist/modules/eudr/components/MitigationActionsSection.js.map +7 -0
  154. package/dist/modules/eudr/components/OrderSelectField.js +88 -0
  155. package/dist/modules/eudr/components/OrderSelectField.js.map +7 -0
  156. package/dist/modules/eudr/components/PlotImportDialog.js +229 -0
  157. package/dist/modules/eudr/components/PlotImportDialog.js.map +7 -0
  158. package/dist/modules/eudr/components/PlotMapPreview.js +35 -0
  159. package/dist/modules/eudr/components/PlotMapPreview.js.map +7 -0
  160. package/dist/modules/eudr/components/PlotMapPreviewImpl.js +97 -0
  161. package/dist/modules/eudr/components/PlotMapPreviewImpl.js.map +7 -0
  162. package/dist/modules/eudr/components/PlotMultiSelectField.js +198 -0
  163. package/dist/modules/eudr/components/PlotMultiSelectField.js.map +7 -0
  164. package/dist/modules/eudr/components/RiskCriteriaField.js +128 -0
  165. package/dist/modules/eudr/components/RiskCriteriaField.js.map +7 -0
  166. package/dist/modules/eudr/components/StatementLifecycleBar.js +274 -0
  167. package/dist/modules/eudr/components/StatementLifecycleBar.js.map +7 -0
  168. package/dist/modules/eudr/components/StatementReadinessChecklist.js +56 -0
  169. package/dist/modules/eudr/components/StatementReadinessChecklist.js.map +7 -0
  170. package/dist/modules/eudr/components/StatementRiskSection.js +179 -0
  171. package/dist/modules/eudr/components/StatementRiskSection.js.map +7 -0
  172. package/dist/modules/eudr/components/crudErrorI18n.js +31 -0
  173. package/dist/modules/eudr/components/crudErrorI18n.js.map +7 -0
  174. package/dist/modules/eudr/components/formConfig.js +593 -0
  175. package/dist/modules/eudr/components/formConfig.js.map +7 -0
  176. package/dist/modules/eudr/components/plotForm.js +68 -0
  177. package/dist/modules/eudr/components/plotForm.js.map +7 -0
  178. package/dist/modules/eudr/data/enrichers.js +62 -0
  179. package/dist/modules/eudr/data/enrichers.js.map +7 -0
  180. package/dist/modules/eudr/data/entities.js +437 -0
  181. package/dist/modules/eudr/data/entities.js.map +7 -0
  182. package/dist/modules/eudr/data/validators.js +271 -0
  183. package/dist/modules/eudr/data/validators.js.map +7 -0
  184. package/dist/modules/eudr/encryption.js +33 -0
  185. package/dist/modules/eudr/encryption.js.map +7 -0
  186. package/dist/modules/eudr/events.js +38 -0
  187. package/dist/modules/eudr/events.js.map +7 -0
  188. package/dist/modules/eudr/index.js +15 -0
  189. package/dist/modules/eudr/index.js.map +7 -0
  190. package/dist/modules/eudr/lib/annual-report.js +104 -0
  191. package/dist/modules/eudr/lib/annual-report.js.map +7 -0
  192. package/dist/modules/eudr/lib/completeness.js +64 -0
  193. package/dist/modules/eudr/lib/completeness.js.map +7 -0
  194. package/dist/modules/eudr/lib/detail-read-scope.js +16 -0
  195. package/dist/modules/eudr/lib/detail-read-scope.js.map +7 -0
  196. package/dist/modules/eudr/lib/geometry.js +142 -0
  197. package/dist/modules/eudr/lib/geometry.js.map +7 -0
  198. package/dist/modules/eudr/lib/notifications.js +56 -0
  199. package/dist/modules/eudr/lib/notifications.js.map +7 -0
  200. package/dist/modules/eudr/lib/plural.js +26 -0
  201. package/dist/modules/eudr/lib/plural.js.map +7 -0
  202. package/dist/modules/eudr/lib/reference-data.js +240 -0
  203. package/dist/modules/eudr/lib/reference-data.js.map +7 -0
  204. package/dist/modules/eudr/lib/species.js +10 -0
  205. package/dist/modules/eudr/lib/species.js.map +7 -0
  206. package/dist/modules/eudr/lib/statement-lifecycle.js +84 -0
  207. package/dist/modules/eudr/lib/statement-lifecycle.js.map +7 -0
  208. package/dist/modules/eudr/lib/statement-seeding.js +49 -0
  209. package/dist/modules/eudr/lib/statement-seeding.js.map +7 -0
  210. package/dist/modules/eudr/migrations/Migration20260706102002_eudr.js +15 -0
  211. package/dist/modules/eudr/migrations/Migration20260706102002_eudr.js.map +7 -0
  212. package/dist/modules/eudr/migrations/Migration20260706152612_eudr.js +24 -0
  213. package/dist/modules/eudr/migrations/Migration20260706152612_eudr.js.map +7 -0
  214. package/dist/modules/eudr/migrations/Migration20260722100000_eudr.js +15 -0
  215. package/dist/modules/eudr/migrations/Migration20260722100000_eudr.js.map +7 -0
  216. package/dist/modules/eudr/notifications.js +58 -0
  217. package/dist/modules/eudr/notifications.js.map +7 -0
  218. package/dist/modules/eudr/search.js +186 -0
  219. package/dist/modules/eudr/search.js.map +7 -0
  220. package/dist/modules/eudr/setup.js +12 -0
  221. package/dist/modules/eudr/setup.js.map +7 -0
  222. package/dist/modules/eudr/subscribers/notify-mitigation-completed.js +34 -0
  223. package/dist/modules/eudr/subscribers/notify-mitigation-completed.js.map +7 -0
  224. package/dist/modules/eudr/subscribers/notify-risk-concluded.js +35 -0
  225. package/dist/modules/eudr/subscribers/notify-risk-concluded.js.map +7 -0
  226. package/dist/modules/eudr/subscribers/notify-statement-reference-issued.js +37 -0
  227. package/dist/modules/eudr/subscribers/notify-statement-reference-issued.js.map +7 -0
  228. package/dist/modules/eudr/subscribers/notify-statement-submitted.js +34 -0
  229. package/dist/modules/eudr/subscribers/notify-statement-submitted.js.map +7 -0
  230. package/dist/modules/eudr/subscribers/notify-statement-withdrawn.js +34 -0
  231. package/dist/modules/eudr/subscribers/notify-statement-withdrawn.js.map +7 -0
  232. package/dist/modules/eudr/subscribers/recompute-completeness-on-attachment-created.js +124 -0
  233. package/dist/modules/eudr/subscribers/recompute-completeness-on-attachment-created.js.map +7 -0
  234. package/dist/modules/eudr/subscribers/recompute-completeness-on-attachment-deleted.js +22 -0
  235. package/dist/modules/eudr/subscribers/recompute-completeness-on-attachment-deleted.js.map +7 -0
  236. package/dist/modules/eudr/widgets/dashboard/compliance-overview/widget.client.js +203 -0
  237. package/dist/modules/eudr/widgets/dashboard/compliance-overview/widget.client.js.map +7 -0
  238. package/dist/modules/eudr/widgets/dashboard/compliance-overview/widget.js +23 -0
  239. package/dist/modules/eudr/widgets/dashboard/compliance-overview/widget.js.map +7 -0
  240. package/dist/modules/eudr/widgets/injection/eudr-product-column/widget.client.js +19 -0
  241. package/dist/modules/eudr/widgets/injection/eudr-product-column/widget.client.js.map +7 -0
  242. package/dist/modules/eudr/widgets/injection/eudr-product-column/widget.js +31 -0
  243. package/dist/modules/eudr/widgets/injection/eudr-product-column/widget.js.map +7 -0
  244. package/dist/modules/eudr/widgets/injection/order-compliance/widget.client.js +100 -0
  245. package/dist/modules/eudr/widgets/injection/order-compliance/widget.client.js.map +7 -0
  246. package/dist/modules/eudr/widgets/injection/order-compliance/widget.js +17 -0
  247. package/dist/modules/eudr/widgets/injection/order-compliance/widget.js.map +7 -0
  248. package/dist/modules/eudr/widgets/injection/supplier-compliance/widget.client.js +116 -0
  249. package/dist/modules/eudr/widgets/injection/supplier-compliance/widget.client.js.map +7 -0
  250. package/dist/modules/eudr/widgets/injection/supplier-compliance/widget.js +17 -0
  251. package/dist/modules/eudr/widgets/injection/supplier-compliance/widget.js.map +7 -0
  252. package/dist/modules/eudr/widgets/injection-table.js +32 -0
  253. package/dist/modules/eudr/widgets/injection-table.js.map +7 -0
  254. package/dist/modules/notifications/lib/notificationService.js +67 -3
  255. package/dist/modules/notifications/lib/notificationService.js.map +2 -2
  256. package/dist/modules/query_index/lib/engine.js +121 -48
  257. package/dist/modules/query_index/lib/engine.js.map +2 -2
  258. package/dist/modules/sales/api/documents/factory.js +17 -0
  259. package/dist/modules/sales/api/documents/factory.js.map +2 -2
  260. package/dist/modules/sales/commands/documents.js +32 -18
  261. package/dist/modules/sales/commands/documents.js.map +2 -2
  262. package/dist/modules/sales/data/entities.js +1 -0
  263. package/dist/modules/sales/data/entities.js.map +2 -2
  264. package/dist/modules/sales/migrations/Migration20260806120000_sales_tag_assignment_document_idx.js +17 -0
  265. package/dist/modules/sales/migrations/Migration20260806120000_sales_tag_assignment_document_idx.js.map +7 -0
  266. package/generated/entities/eudr_due_diligence_statement/index.ts +22 -0
  267. package/generated/entities/eudr_evidence_submission/index.ts +24 -0
  268. package/generated/entities/eudr_mitigation_action/index.ts +14 -0
  269. package/generated/entities/eudr_plot/index.ts +18 -0
  270. package/generated/entities/eudr_product_mapping/index.ts +14 -0
  271. package/generated/entities/eudr_risk_assessment/index.ts +16 -0
  272. package/generated/entities.ids.generated.ts +9 -0
  273. package/generated/entity-fields-registry.ts +120 -0
  274. package/package.json +7 -7
  275. package/src/helpers/integration/ui.ts +12 -0
  276. package/src/modules/attachments/fields/attachment.tsx +5 -0
  277. package/src/modules/attachments/lib/crud.ts +2 -0
  278. package/src/modules/eudr/acl.ts +39 -0
  279. package/src/modules/eudr/ai-agents.ts +258 -0
  280. package/src/modules/eudr/ai-tools/compliance-pack.ts +618 -0
  281. package/src/modules/eudr/ai-tools/types.ts +44 -0
  282. package/src/modules/eudr/ai-tools.ts +15 -0
  283. package/src/modules/eudr/api/dashboard/widgets/compliance-overview/route.ts +481 -0
  284. package/src/modules/eudr/api/evidence-submissions/route.ts +335 -0
  285. package/src/modules/eudr/api/mitigation-actions/route.ts +263 -0
  286. package/src/modules/eudr/api/openapi.ts +28 -0
  287. package/src/modules/eudr/api/plots/import/route.ts +369 -0
  288. package/src/modules/eudr/api/plots/route.ts +296 -0
  289. package/src/modules/eudr/api/product-mappings/route.ts +269 -0
  290. package/src/modules/eudr/api/product-mappings/suggestions/apply/route.ts +382 -0
  291. package/src/modules/eudr/api/product-mappings/suggestions/route.ts +169 -0
  292. package/src/modules/eudr/api/reports/annual/route.ts +457 -0
  293. package/src/modules/eudr/api/risk-assessments/route.ts +323 -0
  294. package/src/modules/eudr/api/statements/[id]/export/route.ts +713 -0
  295. package/src/modules/eudr/api/statements/[id]/readiness/route.ts +129 -0
  296. package/src/modules/eudr/api/statements/route.ts +329 -0
  297. package/src/modules/eudr/api/suppliers/compliance/route.ts +241 -0
  298. package/src/modules/eudr/backend/eudr/evidence-submissions/[id]/page.meta.ts +12 -0
  299. package/src/modules/eudr/backend/eudr/evidence-submissions/[id]/page.tsx +545 -0
  300. package/src/modules/eudr/backend/eudr/evidence-submissions/create/page.meta.ts +13 -0
  301. package/src/modules/eudr/backend/eudr/evidence-submissions/create/page.tsx +383 -0
  302. package/src/modules/eudr/backend/eudr/evidence-submissions/page.meta.ts +12 -0
  303. package/src/modules/eudr/backend/eudr/evidence-submissions/page.tsx +379 -0
  304. package/src/modules/eudr/backend/eudr/page.meta.ts +12 -0
  305. package/src/modules/eudr/backend/eudr/page.tsx +477 -0
  306. package/src/modules/eudr/backend/eudr/plots/[id]/page.meta.ts +12 -0
  307. package/src/modules/eudr/backend/eudr/plots/[id]/page.tsx +404 -0
  308. package/src/modules/eudr/backend/eudr/plots/create/page.meta.ts +13 -0
  309. package/src/modules/eudr/backend/eudr/plots/create/page.tsx +267 -0
  310. package/src/modules/eudr/backend/eudr/plots/page.meta.ts +12 -0
  311. package/src/modules/eudr/backend/eudr/plots/page.tsx +442 -0
  312. package/src/modules/eudr/backend/eudr/product-mappings/[id]/page.meta.ts +12 -0
  313. package/src/modules/eudr/backend/eudr/product-mappings/[id]/page.tsx +311 -0
  314. package/src/modules/eudr/backend/eudr/product-mappings/create/page.meta.ts +13 -0
  315. package/src/modules/eudr/backend/eudr/product-mappings/create/page.tsx +190 -0
  316. package/src/modules/eudr/backend/eudr/product-mappings/page.meta.ts +12 -0
  317. package/src/modules/eudr/backend/eudr/product-mappings/page.tsx +344 -0
  318. package/src/modules/eudr/backend/eudr/risk-assessments/[id]/page.meta.ts +12 -0
  319. package/src/modules/eudr/backend/eudr/risk-assessments/[id]/page.tsx +421 -0
  320. package/src/modules/eudr/backend/eudr/risk-assessments/create/page.meta.ts +13 -0
  321. package/src/modules/eudr/backend/eudr/risk-assessments/create/page.tsx +247 -0
  322. package/src/modules/eudr/backend/eudr/risk-assessments/page.meta.ts +12 -0
  323. package/src/modules/eudr/backend/eudr/risk-assessments/page.tsx +383 -0
  324. package/src/modules/eudr/backend/eudr/statements/[id]/page.meta.ts +12 -0
  325. package/src/modules/eudr/backend/eudr/statements/[id]/page.tsx +777 -0
  326. package/src/modules/eudr/backend/eudr/statements/create/page.meta.ts +13 -0
  327. package/src/modules/eudr/backend/eudr/statements/create/page.tsx +511 -0
  328. package/src/modules/eudr/backend/eudr/statements/page.meta.ts +12 -0
  329. package/src/modules/eudr/backend/eudr/statements/page.tsx +372 -0
  330. package/src/modules/eudr/ce.ts +52 -0
  331. package/src/modules/eudr/commands/evidence-submissions.ts +699 -0
  332. package/src/modules/eudr/commands/index.ts +6 -0
  333. package/src/modules/eudr/commands/lifecycle-events.ts +28 -0
  334. package/src/modules/eudr/commands/mitigation-actions.ts +574 -0
  335. package/src/modules/eudr/commands/plots.ts +627 -0
  336. package/src/modules/eudr/commands/product-mappings.ts +556 -0
  337. package/src/modules/eudr/commands/risk-assessments.ts +728 -0
  338. package/src/modules/eudr/commands/statements.ts +933 -0
  339. package/src/modules/eudr/components/CountrySelectField.tsx +77 -0
  340. package/src/modules/eudr/components/GeometryInput.tsx +170 -0
  341. package/src/modules/eudr/components/MappingSuggestionsDialog.tsx +385 -0
  342. package/src/modules/eudr/components/MitigationActionsSection.tsx +417 -0
  343. package/src/modules/eudr/components/OrderSelectField.tsx +116 -0
  344. package/src/modules/eudr/components/PlotImportDialog.tsx +277 -0
  345. package/src/modules/eudr/components/PlotMapPreview.tsx +46 -0
  346. package/src/modules/eudr/components/PlotMapPreviewImpl.tsx +111 -0
  347. package/src/modules/eudr/components/PlotMultiSelectField.tsx +238 -0
  348. package/src/modules/eudr/components/RiskCriteriaField.tsx +173 -0
  349. package/src/modules/eudr/components/StatementLifecycleBar.tsx +363 -0
  350. package/src/modules/eudr/components/StatementReadinessChecklist.tsx +82 -0
  351. package/src/modules/eudr/components/StatementRiskSection.tsx +242 -0
  352. package/src/modules/eudr/components/crudErrorI18n.ts +36 -0
  353. package/src/modules/eudr/components/formConfig.tsx +717 -0
  354. package/src/modules/eudr/components/plotForm.ts +75 -0
  355. package/src/modules/eudr/data/enrichers.ts +82 -0
  356. package/src/modules/eudr/data/entities.ts +369 -0
  357. package/src/modules/eudr/data/validators.ts +357 -0
  358. package/src/modules/eudr/encryption.ts +31 -0
  359. package/src/modules/eudr/events.ts +38 -0
  360. package/src/modules/eudr/i18n/de.json +747 -0
  361. package/src/modules/eudr/i18n/en.json +747 -0
  362. package/src/modules/eudr/i18n/es.json +747 -0
  363. package/src/modules/eudr/i18n/ko.json +747 -0
  364. package/src/modules/eudr/i18n/pl.json +747 -0
  365. package/src/modules/eudr/index.ts +13 -0
  366. package/src/modules/eudr/lib/annual-report.ts +120 -0
  367. package/src/modules/eudr/lib/completeness.ts +90 -0
  368. package/src/modules/eudr/lib/detail-read-scope.ts +44 -0
  369. package/src/modules/eudr/lib/geometry.ts +191 -0
  370. package/src/modules/eudr/lib/notifications.ts +85 -0
  371. package/src/modules/eudr/lib/plural.ts +36 -0
  372. package/src/modules/eudr/lib/reference-data.ts +128 -0
  373. package/src/modules/eudr/lib/species.ts +12 -0
  374. package/src/modules/eudr/lib/statement-lifecycle.ts +109 -0
  375. package/src/modules/eudr/lib/statement-seeding.ts +86 -0
  376. package/src/modules/eudr/migrations/.snapshot-open-mercato.json +2046 -0
  377. package/src/modules/eudr/migrations/Migration20260706102002_eudr.ts +16 -0
  378. package/src/modules/eudr/migrations/Migration20260706152612_eudr.ts +30 -0
  379. package/src/modules/eudr/migrations/Migration20260722100000_eudr.ts +17 -0
  380. package/src/modules/eudr/notifications.ts +56 -0
  381. package/src/modules/eudr/search.ts +212 -0
  382. package/src/modules/eudr/setup.ts +10 -0
  383. package/src/modules/eudr/subscribers/notify-mitigation-completed.ts +56 -0
  384. package/src/modules/eudr/subscribers/notify-risk-concluded.ts +58 -0
  385. package/src/modules/eudr/subscribers/notify-statement-reference-issued.ts +59 -0
  386. package/src/modules/eudr/subscribers/notify-statement-submitted.ts +49 -0
  387. package/src/modules/eudr/subscribers/notify-statement-withdrawn.ts +49 -0
  388. package/src/modules/eudr/subscribers/recompute-completeness-on-attachment-created.ts +189 -0
  389. package/src/modules/eudr/subscribers/recompute-completeness-on-attachment-deleted.ts +31 -0
  390. package/src/modules/eudr/widgets/dashboard/compliance-overview/widget.client.tsx +271 -0
  391. package/src/modules/eudr/widgets/dashboard/compliance-overview/widget.ts +24 -0
  392. package/src/modules/eudr/widgets/injection/eudr-product-column/widget.client.tsx +37 -0
  393. package/src/modules/eudr/widgets/injection/eudr-product-column/widget.ts +30 -0
  394. package/src/modules/eudr/widgets/injection/order-compliance/widget.client.tsx +131 -0
  395. package/src/modules/eudr/widgets/injection/order-compliance/widget.ts +16 -0
  396. package/src/modules/eudr/widgets/injection/supplier-compliance/widget.client.tsx +168 -0
  397. package/src/modules/eudr/widgets/injection/supplier-compliance/widget.ts +16 -0
  398. package/src/modules/eudr/widgets/injection-table.ts +31 -0
  399. package/src/modules/notifications/lib/notificationService.ts +83 -4
  400. package/src/modules/query_index/lib/engine.ts +139 -51
  401. package/src/modules/sales/api/documents/factory.ts +29 -0
  402. package/src/modules/sales/commands/documents.ts +65 -18
  403. package/src/modules/sales/data/entities.ts +1 -0
  404. package/src/modules/sales/migrations/.snapshot-open-mercato.json +10 -0
  405. package/src/modules/sales/migrations/Migration20260806120000_sales_tag_assignment_document_idx.ts +59 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/components/PlotMultiSelectField.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useRouter } from 'next/navigation'\nimport { Plus, X } from 'lucide-react'\nimport { resolveCountryName } from '@open-mercato/shared/lib/location/countries'\nimport { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { LookupSelect, type LookupSelectItem } from '@open-mercato/ui/backend/inputs'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { IconButton } from '@open-mercato/ui/primitives/icon-button'\nimport { PICKER_PAGE_SIZE } from './formConfig'\nimport { translatePlural } from '../lib/plural'\n\ntype PlotOption = {\n id: string\n name: string\n originCountry: string | null\n plotType: string | null\n areaHa: number | string | null\n}\n\ntype PlotListResponse = {\n items?: unknown[]\n}\n\nexport type PlotMultiSelectFieldProps = {\n id: string\n value: string[]\n onChange: (value: string[]) => void\n supplierEntityId?: string | null\n disabled?: boolean\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction readString(record: Record<string, unknown>, key: string): string | null {\n const value = record[key]\n return typeof value === 'string' && value.trim().length > 0 ? value.trim() : null\n}\n\nfunction normalizePlotOption(raw: unknown): PlotOption | null {\n if (!isRecord(raw)) return null\n const id = readString(raw, 'id')\n const name = readString(raw, 'name')\n if (!id || !name) return null\n const areaHa = raw.areaHa\n return {\n id,\n name,\n originCountry: readString(raw, 'originCountry'),\n plotType: readString(raw, 'plotType'),\n areaHa: typeof areaHa === 'number' || typeof areaHa === 'string' ? areaHa : null,\n }\n}\n\nfunction formatArea(value: PlotOption['areaHa'], emptyLabel: string): string {\n if (value === null || value === undefined || value === '') return emptyLabel\n const numeric = typeof value === 'number' ? value : Number(value)\n if (!Number.isFinite(numeric)) return String(value)\n return new Intl.NumberFormat(undefined, { maximumFractionDigits: 4 }).format(numeric)\n}\n\nexport function PlotMultiSelectField({\n id,\n value,\n onChange,\n supplierEntityId,\n disabled,\n}: PlotMultiSelectFieldProps) {\n const translate = useT()\n const locale = useLocale()\n const router = useRouter()\n const [plotNames, setPlotNames] = React.useState<Record<string, string | null>>({})\n const selectedPlotIds = React.useMemo(() => (Array.isArray(value) ? value : []), [value])\n const selectedIds = React.useMemo(() => new Set(selectedPlotIds), [selectedPlotIds])\n const normalizedSupplierId = typeof supplierEntityId === 'string' && supplierEntityId.trim().length > 0\n ? supplierEntityId.trim()\n : null\n const previousSupplierIdRef = React.useRef(normalizedSupplierId)\n\n React.useEffect(() => {\n const previousSupplierId = previousSupplierIdRef.current\n previousSupplierIdRef.current = normalizedSupplierId\n if (previousSupplierId === normalizedSupplierId || selectedPlotIds.length === 0) return\n onChange([])\n }, [normalizedSupplierId, onChange, selectedPlotIds.length])\n\n React.useEffect(() => {\n const missing = selectedPlotIds.filter((plotId) => !(plotId in plotNames))\n if (!missing.length) return\n let cancelled = false\n async function resolveNames() {\n const params = new URLSearchParams({ ids: missing.join(','), pageSize: '100' })\n const call = await apiCall<PlotListResponse>(\n `/api/eudr/plots?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (cancelled) return\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const resolved: Record<string, string | null> = {}\n for (const plotId of missing) resolved[plotId] = null\n for (const item of items) {\n const option = normalizePlotOption(item)\n if (option) resolved[option.id] = option.name\n }\n setPlotNames((current) => ({ ...current, ...resolved }))\n }\n resolveNames().catch(() => {})\n return () => {\n cancelled = true\n }\n }, [plotNames, selectedPlotIds])\n\n const plotSubtitle = React.useCallback((plot: PlotOption): string => {\n const country = plot.originCountry\n ? `${resolveCountryName(plot.originCountry, { locale })} (${plot.originCountry})`\n : translate('eudr.common.empty')\n const plotType = plot.plotType ?? 'point'\n const area = translate('eudr.plots.list.areaHaValue', {\n value: formatArea(plot.areaHa, translate('eudr.common.empty')),\n })\n return `${country} - ${translate(`eudr.plotType.${plotType}`)} - ${area}`\n }, [locale, translate])\n\n const fetchPlotItems = React.useCallback(async (query: string): Promise<LookupSelectItem[]> => {\n if (!normalizedSupplierId) return []\n const params = new URLSearchParams({\n page: '1',\n pageSize: String(PICKER_PAGE_SIZE),\n supplierEntityId: normalizedSupplierId,\n isActive: 'true',\n })\n if (query) params.set('search', query)\n const call = await apiCall<PlotListResponse>(\n `/api/eudr/plots?${params.toString()}`,\n undefined,\n { fallback: { items: [] } },\n )\n if (!call.ok) {\n flash(translate('eudr.evidenceSubmissions.form.plotsLoadError'), 'error')\n return []\n }\n const items = Array.isArray(call.result?.items) ? call.result.items : []\n const options = items\n .map((item) => normalizePlotOption(item))\n .filter((option): option is PlotOption => option !== null)\n setPlotNames((current) => {\n const next = { ...current }\n for (const option of options) next[option.id] = option.name\n return next\n })\n return options.map((option) => ({\n id: option.id,\n title: option.name,\n subtitle: plotSubtitle(option),\n disabled: selectedIds.has(option.id),\n }))\n }, [normalizedSupplierId, plotSubtitle, selectedIds, translate])\n\n const addPlot = React.useCallback((plotId: string | null) => {\n if (!plotId || selectedIds.has(plotId)) return\n onChange([...selectedPlotIds, plotId])\n }, [onChange, selectedIds, selectedPlotIds])\n\n const removePlot = React.useCallback((plotId: string) => {\n onChange(selectedPlotIds.filter((entry) => entry !== plotId))\n }, [onChange, selectedPlotIds])\n\n return (\n <div id={id} className=\"space-y-3\">\n {!normalizedSupplierId ? (\n <p className=\"rounded-md border border-dashed border-border/70 bg-muted/30 px-3 py-2 text-sm text-muted-foreground\">\n {translate('eudr.evidenceSubmissions.form.plotsSupplierHint')}\n </p>\n ) : (\n <>\n <div className=\"flex items-center justify-between gap-3\">\n <p className=\"text-sm text-muted-foreground\">\n {translatePlural(translate, locale, 'eudr.evidenceSubmissions.form.plotsSelectedCount', selectedPlotIds.length)}\n </p>\n <Button\n type=\"button\"\n variant=\"link\"\n size=\"sm\"\n onClick={() => router.push('/backend/eudr/plots/create')}\n >\n <Plus className=\"size-4\" aria-hidden=\"true\" />\n {translate('eudr.plots.list.actions.create')}\n </Button>\n </div>\n {selectedPlotIds.length > 0 ? (\n <div className=\"flex flex-wrap gap-2\">\n {value\n .filter((plotId) => plotId in plotNames)\n .map((plotId) => {\n const name = plotNames[plotId] ?? translate('eudr.common.recordUnavailable')\n return (\n <span\n key={plotId}\n className=\"inline-flex items-center gap-1 rounded-full border border-border bg-muted/30 py-0.5 pl-3 pr-1 text-sm text-foreground\"\n >\n <span className=\"max-w-56 truncate\">{name}</span>\n <IconButton\n type=\"button\"\n variant=\"ghost\"\n size=\"xs\"\n disabled={disabled}\n aria-label={translate('eudr.evidenceSubmissions.form.plotsRemove', { name })}\n onClick={() => removePlot(plotId)}\n >\n <X className=\"size-3\" aria-hidden=\"true\" />\n </IconButton>\n </span>\n )\n })}\n </div>\n ) : null}\n <LookupSelect\n key={normalizedSupplierId}\n value={null}\n minQuery={0}\n disabled={disabled}\n searchPlaceholder={translate('eudr.plots.list.searchPlaceholder')}\n fetchItems={fetchPlotItems}\n onChange={addPlot}\n />\n </>\n )}\n </div>\n )\n}\n\nexport default PlotMultiSelectField\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,128 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
5
+ import { Alert } from "@open-mercato/ui/primitives/alert";
6
+ import { Input } from "@open-mercato/ui/primitives/input";
7
+ import { Label } from "@open-mercato/ui/primitives/label";
8
+ import {
9
+ SegmentedControl,
10
+ SegmentedControlItem
11
+ } from "@open-mercato/ui/primitives/segmented-control";
12
+ import { EUDR_RISK_CRITERIA_GROUPS } from "../lib/reference-data.js";
13
+ import {
14
+ EUDR_CRITERIA_ANSWERS
15
+ } from "../data/validators.js";
16
+ const criteriaKeys = new Set(
17
+ EUDR_RISK_CRITERIA_GROUPS.flatMap((group) => [...group.criteria])
18
+ );
19
+ function isRecord(value) {
20
+ return value !== null && typeof value === "object" && !Array.isArray(value);
21
+ }
22
+ function isCriteriaAnswer(value) {
23
+ return typeof value === "string" && EUDR_CRITERIA_ANSWERS.some((answer) => answer === value);
24
+ }
25
+ function normalizeCriteriaValue(value) {
26
+ if (!isRecord(value)) return {};
27
+ const normalized = {};
28
+ for (const [key, rawEntry] of Object.entries(value)) {
29
+ if (!criteriaKeys.has(key) || !isRecord(rawEntry) || !isCriteriaAnswer(rawEntry.answer)) continue;
30
+ const note = typeof rawEntry.note === "string" && rawEntry.note.trim().length > 0 ? rawEntry.note : null;
31
+ normalized[key] = note ? { answer: rawEntry.answer, note } : { answer: rawEntry.answer };
32
+ }
33
+ return normalized;
34
+ }
35
+ function countAnsweredCriteria(value) {
36
+ const criteria = normalizeCriteriaValue(value);
37
+ return { answered: Object.keys(criteria).length, total: criteriaKeys.size };
38
+ }
39
+ function RiskConclusionCriteriaWarning({
40
+ conclusion,
41
+ criteria
42
+ }) {
43
+ const translate = useT();
44
+ if (conclusion !== "negligible") return null;
45
+ const { answered, total } = countAnsweredCriteria(criteria);
46
+ if (answered >= total) return null;
47
+ return /* @__PURE__ */ jsx(Alert, { status: "warning", style: "lighter", children: /* @__PURE__ */ jsx("div", { className: "text-sm leading-5", children: translate("eudr.riskAssessments.form.negligibleCriteriaWarning", { answered, total }) }) });
48
+ }
49
+ function RiskCriteriaField({
50
+ id,
51
+ value,
52
+ onChange,
53
+ disabled
54
+ }) {
55
+ const translate = useT();
56
+ const criteria = React.useMemo(() => normalizeCriteriaValue(value), [value]);
57
+ const total = criteriaKeys.size;
58
+ const answered = Object.keys(criteria).filter((key) => criteriaKeys.has(key)).length;
59
+ const updateAnswer = React.useCallback((criterionKey, answer) => {
60
+ const current = criteria[criterionKey];
61
+ const next = { ...criteria };
62
+ const note = answer === "concern" && current?.note ? current.note : null;
63
+ next[criterionKey] = note ? { answer, note } : { answer };
64
+ onChange(next);
65
+ }, [criteria, onChange]);
66
+ const updateNote = React.useCallback((criterionKey, note) => {
67
+ const current = criteria[criterionKey];
68
+ if (!current || current.answer !== "concern") return;
69
+ const trimmed = note.trim();
70
+ onChange({
71
+ ...criteria,
72
+ [criterionKey]: trimmed ? { answer: current.answer, note } : { answer: current.answer }
73
+ });
74
+ }, [criteria, onChange]);
75
+ return /* @__PURE__ */ jsxs("div", { id, className: "space-y-5", children: [
76
+ /* @__PURE__ */ jsx("div", { className: "text-sm text-muted-foreground", children: translate("eudr.risk.criteria.answeredCount", { answered, total }) }),
77
+ EUDR_RISK_CRITERIA_GROUPS.map((group) => /* @__PURE__ */ jsxs("section", { className: "space-y-3", children: [
78
+ /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold", children: translate(`eudr.risk.criteriaGroup.${group.key}`) }),
79
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: group.criteria.map((criterionKey) => {
80
+ const entry = criteria[criterionKey];
81
+ const criterionId = `${id}-${criterionKey}`;
82
+ return /* @__PURE__ */ jsxs("div", { className: "space-y-2 rounded-md border border-border bg-background p-3", children: [
83
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2 lg:flex-row lg:items-center lg:justify-between", children: [
84
+ /* @__PURE__ */ jsx(Label, { htmlFor: criterionId, className: "text-sm font-medium", children: translate(`eudr.risk.criteria.${criterionKey}`) }),
85
+ /* @__PURE__ */ jsx(
86
+ SegmentedControl,
87
+ {
88
+ id: criterionId,
89
+ value: entry?.answer,
90
+ onValueChange: (nextValue) => {
91
+ if (isCriteriaAnswer(nextValue)) updateAnswer(criterionKey, nextValue);
92
+ },
93
+ disabled,
94
+ "aria-label": translate(`eudr.risk.criteria.${criterionKey}`),
95
+ children: EUDR_CRITERIA_ANSWERS.map((answer) => /* @__PURE__ */ jsx(
96
+ SegmentedControlItem,
97
+ {
98
+ value: answer,
99
+ className: answer === "concern" ? "data-[state=checked]:bg-status-warning-bg data-[state=checked]:text-status-warning-text" : void 0,
100
+ children: translate(`eudr.risk.criteriaAnswer.${answer}`)
101
+ },
102
+ answer
103
+ ))
104
+ }
105
+ )
106
+ ] }),
107
+ entry?.answer === "concern" ? /* @__PURE__ */ jsx(
108
+ Input,
109
+ {
110
+ value: entry.note ?? "",
111
+ disabled,
112
+ placeholder: translate("eudr.risk.criteria.notePlaceholder"),
113
+ onChange: (event) => updateNote(criterionKey, event.target.value)
114
+ }
115
+ ) : null
116
+ ] }, criterionKey);
117
+ }) })
118
+ ] }, group.key))
119
+ ] });
120
+ }
121
+ var RiskCriteriaField_default = RiskCriteriaField;
122
+ export {
123
+ RiskConclusionCriteriaWarning,
124
+ RiskCriteriaField,
125
+ countAnsweredCriteria,
126
+ RiskCriteriaField_default as default
127
+ };
128
+ //# sourceMappingURL=RiskCriteriaField.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/components/RiskCriteriaField.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { Alert } from '@open-mercato/ui/primitives/alert'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport {\n SegmentedControl,\n SegmentedControlItem,\n} from '@open-mercato/ui/primitives/segmented-control'\nimport { EUDR_RISK_CRITERIA_GROUPS } from '../lib/reference-data'\nimport {\n EUDR_CRITERIA_ANSWERS,\n type EudrCriteriaAnswer,\n} from '../data/validators'\n\nexport type RiskCriteriaEntry = {\n answer: EudrCriteriaAnswer\n note?: string | null\n}\n\nexport type RiskCriteriaValue = Record<string, RiskCriteriaEntry>\n\nexport type RiskCriteriaFieldProps = {\n id: string\n value: unknown\n onChange: (value: RiskCriteriaValue) => void\n disabled?: boolean\n}\n\nconst criteriaKeys = new Set<string>(\n EUDR_RISK_CRITERIA_GROUPS.flatMap((group) => [...group.criteria]),\n)\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction isCriteriaAnswer(value: unknown): value is EudrCriteriaAnswer {\n return typeof value === 'string' && EUDR_CRITERIA_ANSWERS.some((answer) => answer === value)\n}\n\nfunction normalizeCriteriaValue(value: unknown): RiskCriteriaValue {\n if (!isRecord(value)) return {}\n const normalized: RiskCriteriaValue = {}\n for (const [key, rawEntry] of Object.entries(value)) {\n if (!criteriaKeys.has(key) || !isRecord(rawEntry) || !isCriteriaAnswer(rawEntry.answer)) continue\n const note = typeof rawEntry.note === 'string' && rawEntry.note.trim().length > 0\n ? rawEntry.note\n : null\n normalized[key] = note ? { answer: rawEntry.answer, note } : { answer: rawEntry.answer }\n }\n return normalized\n}\n\nexport function countAnsweredCriteria(value: unknown): { answered: number; total: number } {\n const criteria = normalizeCriteriaValue(value)\n return { answered: Object.keys(criteria).length, total: criteriaKeys.size }\n}\n\nexport function RiskConclusionCriteriaWarning({\n conclusion,\n criteria,\n}: {\n conclusion: unknown\n criteria: unknown\n}) {\n const translate = useT()\n if (conclusion !== 'negligible') return null\n const { answered, total } = countAnsweredCriteria(criteria)\n if (answered >= total) return null\n return (\n <Alert status=\"warning\" style=\"lighter\">\n <div className=\"text-sm leading-5\">\n {translate('eudr.riskAssessments.form.negligibleCriteriaWarning', { answered, total })}\n </div>\n </Alert>\n )\n}\n\nexport function RiskCriteriaField({\n id,\n value,\n onChange,\n disabled,\n}: RiskCriteriaFieldProps) {\n const translate = useT()\n const criteria = React.useMemo(() => normalizeCriteriaValue(value), [value])\n const total = criteriaKeys.size\n const answered = Object.keys(criteria).filter((key) => criteriaKeys.has(key)).length\n\n const updateAnswer = React.useCallback((criterionKey: string, answer: EudrCriteriaAnswer) => {\n const current = criteria[criterionKey]\n const next: RiskCriteriaValue = { ...criteria }\n const note = answer === 'concern' && current?.note ? current.note : null\n next[criterionKey] = note ? { answer, note } : { answer }\n onChange(next)\n }, [criteria, onChange])\n\n const updateNote = React.useCallback((criterionKey: string, note: string) => {\n const current = criteria[criterionKey]\n if (!current || current.answer !== 'concern') return\n const trimmed = note.trim()\n onChange({\n ...criteria,\n [criterionKey]: trimmed\n ? { answer: current.answer, note }\n : { answer: current.answer },\n })\n }, [criteria, onChange])\n\n return (\n <div id={id} className=\"space-y-5\">\n <div className=\"text-sm text-muted-foreground\">\n {translate('eudr.risk.criteria.answeredCount', { answered, total })}\n </div>\n {EUDR_RISK_CRITERIA_GROUPS.map((group) => (\n <section key={group.key} className=\"space-y-3\">\n <h3 className=\"text-sm font-semibold\">\n {translate(`eudr.risk.criteriaGroup.${group.key}`)}\n </h3>\n <div className=\"space-y-3\">\n {group.criteria.map((criterionKey) => {\n const entry = criteria[criterionKey]\n const criterionId = `${id}-${criterionKey}`\n return (\n <div key={criterionKey} className=\"space-y-2 rounded-md border border-border bg-background p-3\">\n <div className=\"flex flex-col gap-2 lg:flex-row lg:items-center lg:justify-between\">\n <Label htmlFor={criterionId} className=\"text-sm font-medium\">\n {translate(`eudr.risk.criteria.${criterionKey}`)}\n </Label>\n <SegmentedControl\n id={criterionId}\n value={entry?.answer}\n onValueChange={(nextValue) => {\n if (isCriteriaAnswer(nextValue)) updateAnswer(criterionKey, nextValue)\n }}\n disabled={disabled}\n aria-label={translate(`eudr.risk.criteria.${criterionKey}`)}\n >\n {EUDR_CRITERIA_ANSWERS.map((answer) => (\n <SegmentedControlItem\n key={answer}\n value={answer}\n className={answer === 'concern'\n ? 'data-[state=checked]:bg-status-warning-bg data-[state=checked]:text-status-warning-text'\n : undefined}\n >\n {translate(`eudr.risk.criteriaAnswer.${answer}`)}\n </SegmentedControlItem>\n ))}\n </SegmentedControl>\n </div>\n {entry?.answer === 'concern' ? (\n <Input\n value={entry.note ?? ''}\n disabled={disabled}\n placeholder={translate('eudr.risk.criteria.notePlaceholder')}\n onChange={(event) => updateNote(criterionKey, event.target.value)}\n />\n ) : null}\n </div>\n )\n })}\n </div>\n </section>\n ))}\n </div>\n )\n}\n\nexport default RiskCriteriaField\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,274 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { CheckCircle2 } from "lucide-react";
5
+ import { useLocale, useT } from "@open-mercato/shared/lib/i18n/context";
6
+ import { CrudForm } from "@open-mercato/ui/backend/CrudForm";
7
+ import { useConfirmDialog } from "@open-mercato/ui/backend/confirm-dialog";
8
+ import { useGuardedMutation } from "@open-mercato/ui/backend/injection/useGuardedMutation";
9
+ import { buildOptimisticLockHeader, extractOptimisticLockConflict } from "@open-mercato/ui/backend/utils/optimisticLock";
10
+ import { flash } from "@open-mercato/ui/backend/FlashMessages";
11
+ import { updateCrud } from "@open-mercato/ui/backend/utils/crud";
12
+ import { createCrudFormError } from "@open-mercato/ui/backend/utils/serverErrors";
13
+ import { withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
14
+ import {
15
+ Alert,
16
+ AlertTitle
17
+ } from "@open-mercato/ui/primitives/alert";
18
+ import { Button } from "@open-mercato/ui/primitives/button";
19
+ import {
20
+ Dialog,
21
+ DialogContent,
22
+ DialogHeader,
23
+ DialogTitle
24
+ } from "@open-mercato/ui/primitives/dialog";
25
+ import { StatusBadge } from "@open-mercato/ui/primitives/status-badge";
26
+ import {
27
+ EUDR_AMEND_WINDOW_MS,
28
+ EUDR_STATEMENT_TRANSITIONS
29
+ } from "../lib/statement-lifecycle.js";
30
+ import { statusBadgeVariant } from "./formConfig.js";
31
+ function isRecord(value) {
32
+ return value !== null && typeof value === "object" && !Array.isArray(value);
33
+ }
34
+ function extractGateReasons(error) {
35
+ const candidates = [];
36
+ if (isRecord(error)) {
37
+ candidates.push(error.details);
38
+ candidates.push(error);
39
+ }
40
+ for (const candidate of candidates) {
41
+ if (!isRecord(candidate) || !Array.isArray(candidate.reasons)) continue;
42
+ return candidate.reasons.filter((reason) => typeof reason === "string" && reason.trim().length > 0).map((reason) => reason.startsWith("eudr.") ? reason : `eudr.gate.${reason}`);
43
+ }
44
+ return [];
45
+ }
46
+ function parseDate(value) {
47
+ if (!value) return null;
48
+ const date = new Date(value);
49
+ return Number.isNaN(date.getTime()) ? null : date;
50
+ }
51
+ function addYears(date, years) {
52
+ const next = new Date(date);
53
+ next.setFullYear(next.getFullYear() + years);
54
+ return next;
55
+ }
56
+ function remainingParts(ms) {
57
+ const totalMinutes = Math.max(0, Math.ceil(ms / 6e4));
58
+ return { hours: Math.floor(totalMinutes / 60), minutes: totalMinutes % 60 };
59
+ }
60
+ function toDateTimeLocalInput(date) {
61
+ const offsetMs = date.getTimezoneOffset() * 6e4;
62
+ return new Date(date.getTime() - offsetMs).toISOString().slice(0, 16);
63
+ }
64
+ function optionalText(value) {
65
+ if (typeof value !== "string") return null;
66
+ const trimmed = value.trim();
67
+ return trimmed.length ? trimmed : null;
68
+ }
69
+ function transitionActionKey(status) {
70
+ return `eudr.lifecycle.actions.to${status.charAt(0).toUpperCase()}${status.slice(1)}`;
71
+ }
72
+ const confirmTitleKeys = {
73
+ draft: "eudr.lifecycle.confirmReturnToDraft",
74
+ submitted: "eudr.lifecycle.confirmSubmit",
75
+ available: "eudr.lifecycle.confirmMarkAvailable",
76
+ withdrawn: "eudr.lifecycle.confirmWithdraw",
77
+ archived: "eudr.lifecycle.confirmArchive"
78
+ };
79
+ const confirmBodyKeys = {
80
+ draft: "eudr.lifecycle.confirmReturnToDraftBody",
81
+ submitted: "eudr.lifecycle.confirmSubmitBody",
82
+ available: "eudr.lifecycle.confirmMarkAvailableBody",
83
+ withdrawn: "eudr.lifecycle.confirmWithdrawBody",
84
+ archived: "eudr.lifecycle.confirmArchiveBody"
85
+ };
86
+ function StatementLifecycleBar({
87
+ statement,
88
+ speciesMissing = false,
89
+ onChanged
90
+ }) {
91
+ const translate = useT();
92
+ const locale = useLocale();
93
+ const { confirm, ConfirmDialogElement } = useConfirmDialog();
94
+ const [now, setNow] = React.useState(() => /* @__PURE__ */ new Date());
95
+ const [referenceDialogOpen, setReferenceDialogOpen] = React.useState(false);
96
+ const [gateReasons, setGateReasons] = React.useState([]);
97
+ const mutationContextId = `eudr-statement-lifecycle:${statement.id}`;
98
+ const { runMutation, retryLastMutation } = useGuardedMutation({
99
+ contextId: mutationContextId,
100
+ blockedMessage: translate("ui.forms.flash.saveBlocked")
101
+ });
102
+ React.useEffect(() => {
103
+ if (statement.status !== "available") return;
104
+ const interval = window.setInterval(() => setNow(/* @__PURE__ */ new Date()), 6e4);
105
+ setNow(/* @__PURE__ */ new Date());
106
+ return () => window.clearInterval(interval);
107
+ }, [statement.status, statement.referenceIssuedAt]);
108
+ const issuedAt = parseDate(statement.referenceIssuedAt);
109
+ const submittedAt = parseDate(statement.submittedAt);
110
+ const amendRemainingMs = statement.status === "available" && issuedAt ? issuedAt.getTime() + EUDR_AMEND_WINDOW_MS - now.getTime() : 0;
111
+ const amendWindowOpen = statement.status === "available" && issuedAt !== null && now.getTime() >= issuedAt.getTime() && amendRemainingMs > 0;
112
+ const retainUntil = submittedAt ? addYears(submittedAt, 5) : null;
113
+ const performTransition = React.useCallback(async (nextStatus, extraPayload) => {
114
+ setGateReasons([]);
115
+ try {
116
+ await runMutation({
117
+ operation: () => withScopedApiRequestHeaders(
118
+ buildOptimisticLockHeader(statement.updatedAt),
119
+ () => updateCrud("eudr/statements", {
120
+ id: statement.id,
121
+ status: nextStatus,
122
+ ...extraPayload ?? {}
123
+ }, {
124
+ errorMessage: translate("eudr.lifecycle.transitionError")
125
+ })
126
+ ),
127
+ context: {
128
+ formId: mutationContextId,
129
+ resourceKind: "eudr.due_diligence_statement",
130
+ resourceId: statement.id,
131
+ retryLastMutation
132
+ },
133
+ mutationPayload: { id: statement.id, status: nextStatus, ...extraPayload ?? {} }
134
+ });
135
+ flash(translate("eudr.lifecycle.transitionSuccess"), "success");
136
+ onChanged();
137
+ return true;
138
+ } catch (error) {
139
+ const reasons = extractGateReasons(error);
140
+ if (reasons.length > 0) {
141
+ setGateReasons(reasons);
142
+ return false;
143
+ }
144
+ if (extractOptimisticLockConflict(error)) {
145
+ return false;
146
+ }
147
+ flash(translate("eudr.lifecycle.transitionError"), "error");
148
+ return false;
149
+ }
150
+ }, [mutationContextId, onChanged, retryLastMutation, runMutation, statement.id, statement.updatedAt, translate]);
151
+ const handleTransitionClick = React.useCallback(async (nextStatus) => {
152
+ if (statement.status === "submitted" && nextStatus === "available") {
153
+ setReferenceDialogOpen(true);
154
+ return;
155
+ }
156
+ const confirmed = await confirm({
157
+ title: translate(confirmTitleKeys[nextStatus]),
158
+ text: translate(confirmBodyKeys[nextStatus]),
159
+ variant: nextStatus === "archived" || nextStatus === "withdrawn" ? "destructive" : "default"
160
+ });
161
+ if (!confirmed) return;
162
+ await performTransition(nextStatus);
163
+ }, [confirm, performTransition, statement.status, translate]);
164
+ const referenceFields = React.useMemo(() => [
165
+ {
166
+ id: "referenceNumber",
167
+ label: translate("eudr.statements.form.referenceNumber"),
168
+ type: "text",
169
+ required: true
170
+ },
171
+ {
172
+ id: "verificationNumber",
173
+ label: translate("eudr.statements.form.verificationNumber"),
174
+ type: "text",
175
+ required: true
176
+ },
177
+ {
178
+ id: "referenceIssuedAt",
179
+ label: translate("eudr.statements.form.referenceIssuedAt"),
180
+ type: "datetime-local",
181
+ maxDate: /* @__PURE__ */ new Date()
182
+ }
183
+ ], [translate]);
184
+ const referenceGroups = React.useMemo(() => [
185
+ {
186
+ id: "reference",
187
+ title: translate("eudr.lifecycle.referenceDialog.details"),
188
+ column: 1,
189
+ fields: ["referenceNumber", "verificationNumber", "referenceIssuedAt"]
190
+ }
191
+ ], [translate]);
192
+ return /* @__PURE__ */ jsxs("section", { className: "space-y-4 rounded-lg border border-border bg-card p-4", children: [
193
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between", children: [
194
+ /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
195
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-wrap items-center gap-2", children: [
196
+ /* @__PURE__ */ jsx("span", { className: "text-sm font-medium", children: translate("eudr.lifecycle.currentStatus") }),
197
+ /* @__PURE__ */ jsx(StatusBadge, { variant: statusBadgeVariant(statement.status), dot: true, children: translate(`eudr.statementStatus.${statement.status}`) }),
198
+ statement.status === "available" && issuedAt ? amendWindowOpen ? /* @__PURE__ */ jsx(StatusBadge, { variant: "info", children: translate("eudr.lifecycle.amendWindowRemaining", remainingParts(amendRemainingMs)) }) : /* @__PURE__ */ jsx(StatusBadge, { variant: "neutral", children: translate("eudr.lifecycle.amendWindowClosed") }) : null,
199
+ speciesMissing ? /* @__PURE__ */ jsx(StatusBadge, { variant: "warning", children: translate("eudr.warnings.speciesMissing") }) : null
200
+ ] }),
201
+ retainUntil ? /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground", children: translate("eudr.lifecycle.retainUntil", { date: retainUntil.toLocaleDateString(locale || void 0) }) }) : null
202
+ ] }),
203
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap items-center gap-2", children: EUDR_STATEMENT_TRANSITIONS[statement.status].map((nextStatus) => /* @__PURE__ */ jsxs(
204
+ Button,
205
+ {
206
+ type: "button",
207
+ variant: nextStatus === "archived" || nextStatus === "withdrawn" ? "outline" : "default",
208
+ onClick: () => void handleTransitionClick(nextStatus),
209
+ children: [
210
+ /* @__PURE__ */ jsx(CheckCircle2, { className: "size-4", "aria-hidden": "true" }),
211
+ translate(transitionActionKey(nextStatus))
212
+ ]
213
+ },
214
+ nextStatus
215
+ )) })
216
+ ] }),
217
+ gateReasons.length > 0 ? /* @__PURE__ */ jsxs(Alert, { status: "warning", style: "lighter", children: [
218
+ /* @__PURE__ */ jsx(AlertTitle, { children: translate("eudr.lifecycle.gateFailureTitle") }),
219
+ /* @__PURE__ */ jsx("div", { className: "text-sm leading-5", children: /* @__PURE__ */ jsx("ul", { className: "list-disc space-y-1 pl-5", children: gateReasons.map((reason) => /* @__PURE__ */ jsx("li", { children: translate(reason) }, reason)) }) })
220
+ ] }) : null,
221
+ /* @__PURE__ */ jsx(Dialog, { open: referenceDialogOpen, onOpenChange: setReferenceDialogOpen, children: /* @__PURE__ */ jsxs(DialogContent, { size: "lg", children: [
222
+ /* @__PURE__ */ jsx(DialogHeader, { children: /* @__PURE__ */ jsx(DialogTitle, { children: translate("eudr.lifecycle.referenceDialog.title") }) }),
223
+ /* @__PURE__ */ jsx(
224
+ CrudForm,
225
+ {
226
+ embedded: true,
227
+ title: translate("eudr.lifecycle.referenceDialog.title"),
228
+ submitLabel: translate("eudr.lifecycle.referenceDialog.submit"),
229
+ fields: referenceFields,
230
+ groups: referenceGroups,
231
+ initialValues: {
232
+ referenceNumber: statement.referenceNumber ?? "",
233
+ verificationNumber: statement.verificationNumber ?? "",
234
+ referenceIssuedAt: statement.referenceIssuedAt ? toDateTimeLocalInput(new Date(statement.referenceIssuedAt)) : toDateTimeLocalInput(/* @__PURE__ */ new Date())
235
+ },
236
+ onSubmit: async (values) => {
237
+ const referenceNumber = optionalText(values.referenceNumber);
238
+ if (!referenceNumber) {
239
+ const message = translate("eudr.lifecycle.referenceDialog.referenceNumberRequired");
240
+ throw createCrudFormError(message, { referenceNumber: message });
241
+ }
242
+ const verificationNumber = optionalText(values.verificationNumber);
243
+ if (!verificationNumber) {
244
+ const message = translate("eudr.lifecycle.referenceDialog.verificationNumberRequired");
245
+ throw createCrudFormError(message, { verificationNumber: message });
246
+ }
247
+ const issuedAtText = optionalText(values.referenceIssuedAt);
248
+ const issuedAt2 = issuedAtText ? new Date(issuedAtText) : /* @__PURE__ */ new Date();
249
+ if (Number.isNaN(issuedAt2.getTime()) || issuedAt2.getTime() > Date.now()) {
250
+ const message = translate("eudr.lifecycle.referenceDialog.referenceIssuedAtInvalid");
251
+ throw createCrudFormError(message, { referenceIssuedAt: message });
252
+ }
253
+ const ok = await performTransition("available", {
254
+ referenceNumber,
255
+ verificationNumber,
256
+ referenceIssuedAt: issuedAt2.toISOString()
257
+ });
258
+ if (!ok) {
259
+ throw createCrudFormError(translate("eudr.lifecycle.transitionBlocked"));
260
+ }
261
+ setReferenceDialogOpen(false);
262
+ }
263
+ }
264
+ )
265
+ ] }) }),
266
+ ConfirmDialogElement
267
+ ] });
268
+ }
269
+ var StatementLifecycleBar_default = StatementLifecycleBar;
270
+ export {
271
+ StatementLifecycleBar,
272
+ StatementLifecycleBar_default as default
273
+ };
274
+ //# sourceMappingURL=StatementLifecycleBar.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/components/StatementLifecycleBar.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { CheckCircle2 } from 'lucide-react'\nimport { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'\nimport { CrudForm, type CrudField, type CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useGuardedMutation } from '@open-mercato/ui/backend/injection/useGuardedMutation'\nimport { buildOptimisticLockHeader, extractOptimisticLockConflict } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { updateCrud } from '@open-mercato/ui/backend/utils/crud'\nimport { createCrudFormError } from '@open-mercato/ui/backend/utils/serverErrors'\nimport { withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport {\n Alert,\n AlertTitle,\n} from '@open-mercato/ui/primitives/alert'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport {\n Dialog,\n DialogContent,\n DialogHeader,\n DialogTitle,\n} from '@open-mercato/ui/primitives/dialog'\nimport { StatusBadge } from '@open-mercato/ui/primitives/status-badge'\nimport type { EudrStatementStatus } from '../data/validators'\nimport {\n EUDR_AMEND_WINDOW_MS,\n EUDR_STATEMENT_TRANSITIONS,\n} from '../lib/statement-lifecycle'\nimport { statusBadgeVariant } from './formConfig'\n\ntype StatementLifecycleRecord = {\n id: string\n status: EudrStatementStatus\n referenceNumber: string | null\n verificationNumber: string | null\n referenceIssuedAt: string | null\n submittedAt: string | null\n updatedAt: string\n}\n\ntype ReferenceFormValues = {\n referenceNumber: string\n verificationNumber: string\n referenceIssuedAt: string\n} & Record<string, unknown>\n\ntype MutationContext = {\n formId: string\n resourceKind: string\n resourceId: string\n retryLastMutation: () => Promise<boolean>\n}\n\nexport type StatementLifecycleBarProps = {\n statement: StatementLifecycleRecord\n speciesMissing?: boolean\n onChanged: () => void\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction extractGateReasons(error: unknown): string[] {\n const candidates: unknown[] = []\n if (isRecord(error)) {\n candidates.push(error.details)\n candidates.push(error)\n }\n for (const candidate of candidates) {\n if (!isRecord(candidate) || !Array.isArray(candidate.reasons)) continue\n return candidate.reasons\n .filter((reason): reason is string => typeof reason === 'string' && reason.trim().length > 0)\n .map((reason) => reason.startsWith('eudr.') ? reason : `eudr.gate.${reason}`)\n }\n return []\n}\n\nfunction parseDate(value: string | null | undefined): Date | null {\n if (!value) return null\n const date = new Date(value)\n return Number.isNaN(date.getTime()) ? null : date\n}\n\nfunction addYears(date: Date, years: number): Date {\n const next = new Date(date)\n next.setFullYear(next.getFullYear() + years)\n return next\n}\n\nfunction remainingParts(ms: number): { hours: number; minutes: number } {\n const totalMinutes = Math.max(0, Math.ceil(ms / 60_000))\n return { hours: Math.floor(totalMinutes / 60), minutes: totalMinutes % 60 }\n}\n\nfunction toDateTimeLocalInput(date: Date): string {\n const offsetMs = date.getTimezoneOffset() * 60_000\n return new Date(date.getTime() - offsetMs).toISOString().slice(0, 16)\n}\n\nfunction optionalText(value: unknown): string | null {\n if (typeof value !== 'string') return null\n const trimmed = value.trim()\n return trimmed.length ? trimmed : null\n}\n\nfunction transitionActionKey(status: EudrStatementStatus): string {\n return `eudr.lifecycle.actions.to${status.charAt(0).toUpperCase()}${status.slice(1)}`\n}\n\nconst confirmTitleKeys: Record<EudrStatementStatus, string> = {\n draft: 'eudr.lifecycle.confirmReturnToDraft',\n submitted: 'eudr.lifecycle.confirmSubmit',\n available: 'eudr.lifecycle.confirmMarkAvailable',\n withdrawn: 'eudr.lifecycle.confirmWithdraw',\n archived: 'eudr.lifecycle.confirmArchive',\n}\n\nconst confirmBodyKeys: Record<EudrStatementStatus, string> = {\n draft: 'eudr.lifecycle.confirmReturnToDraftBody',\n submitted: 'eudr.lifecycle.confirmSubmitBody',\n available: 'eudr.lifecycle.confirmMarkAvailableBody',\n withdrawn: 'eudr.lifecycle.confirmWithdrawBody',\n archived: 'eudr.lifecycle.confirmArchiveBody',\n}\n\nexport function StatementLifecycleBar({\n statement,\n speciesMissing = false,\n onChanged,\n}: StatementLifecycleBarProps) {\n const translate = useT()\n const locale = useLocale()\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n const [now, setNow] = React.useState(() => new Date())\n const [referenceDialogOpen, setReferenceDialogOpen] = React.useState(false)\n const [gateReasons, setGateReasons] = React.useState<string[]>([])\n const mutationContextId = `eudr-statement-lifecycle:${statement.id}`\n const { runMutation, retryLastMutation } = useGuardedMutation<MutationContext>({\n contextId: mutationContextId,\n blockedMessage: translate('ui.forms.flash.saveBlocked'),\n })\n\n React.useEffect(() => {\n if (statement.status !== 'available') return\n const interval = window.setInterval(() => setNow(new Date()), 60_000)\n setNow(new Date())\n return () => window.clearInterval(interval)\n }, [statement.status, statement.referenceIssuedAt])\n\n const issuedAt = parseDate(statement.referenceIssuedAt)\n const submittedAt = parseDate(statement.submittedAt)\n const amendRemainingMs = statement.status === 'available' && issuedAt\n ? issuedAt.getTime() + EUDR_AMEND_WINDOW_MS - now.getTime()\n : 0\n const amendWindowOpen = statement.status === 'available'\n && issuedAt !== null\n && now.getTime() >= issuedAt.getTime()\n && amendRemainingMs > 0\n const retainUntil = submittedAt ? addYears(submittedAt, 5) : null\n\n const performTransition = React.useCallback(async (\n nextStatus: EudrStatementStatus,\n extraPayload?: Record<string, unknown>,\n ): Promise<boolean> => {\n setGateReasons([])\n try {\n await runMutation({\n operation: () => withScopedApiRequestHeaders(\n buildOptimisticLockHeader(statement.updatedAt),\n () => updateCrud('eudr/statements', {\n id: statement.id,\n status: nextStatus,\n ...(extraPayload ?? {}),\n }, {\n errorMessage: translate('eudr.lifecycle.transitionError'),\n }),\n ),\n context: {\n formId: mutationContextId,\n resourceKind: 'eudr.due_diligence_statement',\n resourceId: statement.id,\n retryLastMutation,\n },\n mutationPayload: { id: statement.id, status: nextStatus, ...(extraPayload ?? {}) },\n })\n flash(translate('eudr.lifecycle.transitionSuccess'), 'success')\n onChanged()\n return true\n } catch (error) {\n const reasons = extractGateReasons(error)\n if (reasons.length > 0) {\n setGateReasons(reasons)\n return false\n }\n if (extractOptimisticLockConflict(error)) {\n return false\n }\n flash(translate('eudr.lifecycle.transitionError'), 'error')\n return false\n }\n }, [mutationContextId, onChanged, retryLastMutation, runMutation, statement.id, statement.updatedAt, translate])\n\n const handleTransitionClick = React.useCallback(async (nextStatus: EudrStatementStatus) => {\n if (statement.status === 'submitted' && nextStatus === 'available') {\n setReferenceDialogOpen(true)\n return\n }\n const confirmed = await confirm({\n title: translate(confirmTitleKeys[nextStatus]),\n text: translate(confirmBodyKeys[nextStatus]),\n variant: nextStatus === 'archived' || nextStatus === 'withdrawn' ? 'destructive' : 'default',\n })\n if (!confirmed) return\n await performTransition(nextStatus)\n }, [confirm, performTransition, statement.status, translate])\n\n const referenceFields = React.useMemo<CrudField[]>(() => [\n {\n id: 'referenceNumber',\n label: translate('eudr.statements.form.referenceNumber'),\n type: 'text',\n required: true,\n },\n {\n id: 'verificationNumber',\n label: translate('eudr.statements.form.verificationNumber'),\n type: 'text',\n required: true,\n },\n {\n id: 'referenceIssuedAt',\n label: translate('eudr.statements.form.referenceIssuedAt'),\n type: 'datetime-local',\n maxDate: new Date(),\n },\n ], [translate])\n\n const referenceGroups = React.useMemo<CrudFormGroup[]>(() => [\n {\n id: 'reference',\n title: translate('eudr.lifecycle.referenceDialog.details'),\n column: 1,\n fields: ['referenceNumber', 'verificationNumber', 'referenceIssuedAt'],\n },\n ], [translate])\n\n return (\n <section className=\"space-y-4 rounded-lg border border-border bg-card p-4\">\n <div className=\"flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between\">\n <div className=\"space-y-2\">\n <div className=\"flex flex-wrap items-center gap-2\">\n <span className=\"text-sm font-medium\">{translate('eudr.lifecycle.currentStatus')}</span>\n <StatusBadge variant={statusBadgeVariant(statement.status)} dot>\n {translate(`eudr.statementStatus.${statement.status}`)}\n </StatusBadge>\n {statement.status === 'available' && issuedAt ? (\n amendWindowOpen ? (\n <StatusBadge variant=\"info\">\n {translate('eudr.lifecycle.amendWindowRemaining', remainingParts(amendRemainingMs))}\n </StatusBadge>\n ) : (\n <StatusBadge variant=\"neutral\">\n {translate('eudr.lifecycle.amendWindowClosed')}\n </StatusBadge>\n )\n ) : null}\n {speciesMissing ? (\n <StatusBadge variant=\"warning\">\n {translate('eudr.warnings.speciesMissing')}\n </StatusBadge>\n ) : null}\n </div>\n {retainUntil ? (\n <p className=\"text-sm text-muted-foreground\">\n {translate('eudr.lifecycle.retainUntil', { date: retainUntil.toLocaleDateString(locale || undefined) })}\n </p>\n ) : null}\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n {EUDR_STATEMENT_TRANSITIONS[statement.status].map((nextStatus) => (\n <Button\n key={nextStatus}\n type=\"button\"\n variant={nextStatus === 'archived' || nextStatus === 'withdrawn' ? 'outline' : 'default'}\n onClick={() => void handleTransitionClick(nextStatus)}\n >\n <CheckCircle2 className=\"size-4\" aria-hidden=\"true\" />\n {translate(transitionActionKey(nextStatus))}\n </Button>\n ))}\n </div>\n </div>\n\n {gateReasons.length > 0 ? (\n <Alert status=\"warning\" style=\"lighter\">\n <AlertTitle>{translate('eudr.lifecycle.gateFailureTitle')}</AlertTitle>\n <div className=\"text-sm leading-5\">\n <ul className=\"list-disc space-y-1 pl-5\">\n {gateReasons.map((reason) => (\n <li key={reason}>{translate(reason)}</li>\n ))}\n </ul>\n </div>\n </Alert>\n ) : null}\n\n <Dialog open={referenceDialogOpen} onOpenChange={setReferenceDialogOpen}>\n <DialogContent size=\"lg\">\n <DialogHeader>\n <DialogTitle>{translate('eudr.lifecycle.referenceDialog.title')}</DialogTitle>\n </DialogHeader>\n <CrudForm<ReferenceFormValues>\n embedded\n title={translate('eudr.lifecycle.referenceDialog.title')}\n submitLabel={translate('eudr.lifecycle.referenceDialog.submit')}\n fields={referenceFields}\n groups={referenceGroups}\n initialValues={{\n referenceNumber: statement.referenceNumber ?? '',\n verificationNumber: statement.verificationNumber ?? '',\n referenceIssuedAt: statement.referenceIssuedAt\n ? toDateTimeLocalInput(new Date(statement.referenceIssuedAt))\n : toDateTimeLocalInput(new Date()),\n }}\n onSubmit={async (values) => {\n const referenceNumber = optionalText(values.referenceNumber)\n if (!referenceNumber) {\n const message = translate('eudr.lifecycle.referenceDialog.referenceNumberRequired')\n throw createCrudFormError(message, { referenceNumber: message })\n }\n const verificationNumber = optionalText(values.verificationNumber)\n if (!verificationNumber) {\n const message = translate('eudr.lifecycle.referenceDialog.verificationNumberRequired')\n throw createCrudFormError(message, { verificationNumber: message })\n }\n const issuedAtText = optionalText(values.referenceIssuedAt)\n const issuedAt = issuedAtText ? new Date(issuedAtText) : new Date()\n if (Number.isNaN(issuedAt.getTime()) || issuedAt.getTime() > Date.now()) {\n const message = translate('eudr.lifecycle.referenceDialog.referenceIssuedAtInvalid')\n throw createCrudFormError(message, { referenceIssuedAt: message })\n }\n const ok = await performTransition('available', {\n referenceNumber,\n verificationNumber,\n referenceIssuedAt: issuedAt.toISOString(),\n })\n if (!ok) {\n throw createCrudFormError(translate('eudr.lifecycle.transitionBlocked'))\n }\n setReferenceDialogOpen(false)\n }}\n />\n </DialogContent>\n </Dialog>\n {ConfirmDialogElement}\n </section>\n )\n}\n\nexport default StatementLifecycleBar\n"],
5
+ "mappings": ";AA6PU,SACE,KADF;AA3PV,YAAY,WAAW;AACvB,SAAS,oBAAoB;AAC7B,SAAS,WAAW,YAAY;AAChC,SAAS,gBAAoD;AAC7D,SAAS,wBAAwB;AACjC,SAAS,0BAA0B;AACnC,SAAS,2BAA2B,qCAAqC;AACzE,SAAS,aAAa;AACtB,SAAS,kBAAkB;AAC3B,SAAS,2BAA2B;AACpC,SAAS,mCAAmC;AAC5C;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,cAAc;AACvB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,mBAAmB;AAE5B;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP,SAAS,0BAA0B;AA+BnC,SAAS,SAAS,OAAkD;AAClE,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC5E;AAEA,SAAS,mBAAmB,OAA0B;AACpD,QAAM,aAAwB,CAAC;AAC/B,MAAI,SAAS,KAAK,GAAG;AACnB,eAAW,KAAK,MAAM,OAAO;AAC7B,eAAW,KAAK,KAAK;AAAA,EACvB;AACA,aAAW,aAAa,YAAY;AAClC,QAAI,CAAC,SAAS,SAAS,KAAK,CAAC,MAAM,QAAQ,UAAU,OAAO,EAAG;AAC/D,WAAO,UAAU,QACd,OAAO,CAAC,WAA6B,OAAO,WAAW,YAAY,OAAO,KAAK,EAAE,SAAS,CAAC,EAC3F,IAAI,CAAC,WAAW,OAAO,WAAW,OAAO,IAAI,SAAS,aAAa,MAAM,EAAE;AAAA,EAChF;AACA,SAAO,CAAC;AACV;AAEA,SAAS,UAAU,OAA+C;AAChE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,SAAO,OAAO,MAAM,KAAK,QAAQ,CAAC,IAAI,OAAO;AAC/C;AAEA,SAAS,SAAS,MAAY,OAAqB;AACjD,QAAM,OAAO,IAAI,KAAK,IAAI;AAC1B,OAAK,YAAY,KAAK,YAAY,IAAI,KAAK;AAC3C,SAAO;AACT;AAEA,SAAS,eAAe,IAAgD;AACtE,QAAM,eAAe,KAAK,IAAI,GAAG,KAAK,KAAK,KAAK,GAAM,CAAC;AACvD,SAAO,EAAE,OAAO,KAAK,MAAM,eAAe,EAAE,GAAG,SAAS,eAAe,GAAG;AAC5E;AAEA,SAAS,qBAAqB,MAAoB;AAChD,QAAM,WAAW,KAAK,kBAAkB,IAAI;AAC5C,SAAO,IAAI,KAAK,KAAK,QAAQ,IAAI,QAAQ,EAAE,YAAY,EAAE,MAAM,GAAG,EAAE;AACtE;AAEA,SAAS,aAAa,OAA+B;AACnD,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,QAAM,UAAU,MAAM,KAAK;AAC3B,SAAO,QAAQ,SAAS,UAAU;AACpC;AAEA,SAAS,oBAAoB,QAAqC;AAChE,SAAO,4BAA4B,OAAO,OAAO,CAAC,EAAE,YAAY,CAAC,GAAG,OAAO,MAAM,CAAC,CAAC;AACrF;AAEA,MAAM,mBAAwD;AAAA,EAC5D,OAAO;AAAA,EACP,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AACZ;AAEA,MAAM,kBAAuD;AAAA,EAC3D,OAAO;AAAA,EACP,WAAW;AAAA,EACX,WAAW;AAAA,EACX,WAAW;AAAA,EACX,UAAU;AACZ;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA,iBAAiB;AAAA,EACjB;AACF,GAA+B;AAC7B,QAAM,YAAY,KAAK;AACvB,QAAM,SAAS,UAAU;AACzB,QAAM,EAAE,SAAS,qBAAqB,IAAI,iBAAiB;AAC3D,QAAM,CAAC,KAAK,MAAM,IAAI,MAAM,SAAS,MAAM,oBAAI,KAAK,CAAC;AACrD,QAAM,CAAC,qBAAqB,sBAAsB,IAAI,MAAM,SAAS,KAAK;AAC1E,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAmB,CAAC,CAAC;AACjE,QAAM,oBAAoB,4BAA4B,UAAU,EAAE;AAClE,QAAM,EAAE,aAAa,kBAAkB,IAAI,mBAAoC;AAAA,IAC7E,WAAW;AAAA,IACX,gBAAgB,UAAU,4BAA4B;AAAA,EACxD,CAAC;AAED,QAAM,UAAU,MAAM;AACpB,QAAI,UAAU,WAAW,YAAa;AACtC,UAAM,WAAW,OAAO,YAAY,MAAM,OAAO,oBAAI,KAAK,CAAC,GAAG,GAAM;AACpE,WAAO,oBAAI,KAAK,CAAC;AACjB,WAAO,MAAM,OAAO,cAAc,QAAQ;AAAA,EAC5C,GAAG,CAAC,UAAU,QAAQ,UAAU,iBAAiB,CAAC;AAElD,QAAM,WAAW,UAAU,UAAU,iBAAiB;AACtD,QAAM,cAAc,UAAU,UAAU,WAAW;AACnD,QAAM,mBAAmB,UAAU,WAAW,eAAe,WACzD,SAAS,QAAQ,IAAI,uBAAuB,IAAI,QAAQ,IACxD;AACJ,QAAM,kBAAkB,UAAU,WAAW,eACxC,aAAa,QACb,IAAI,QAAQ,KAAK,SAAS,QAAQ,KAClC,mBAAmB;AACxB,QAAM,cAAc,cAAc,SAAS,aAAa,CAAC,IAAI;AAE7D,QAAM,oBAAoB,MAAM,YAAY,OAC1C,YACA,iBACqB;AACrB,mBAAe,CAAC,CAAC;AACjB,QAAI;AACF,YAAM,YAAY;AAAA,QAChB,WAAW,MAAM;AAAA,UACf,0BAA0B,UAAU,SAAS;AAAA,UAC7C,MAAM,WAAW,mBAAmB;AAAA,YAClC,IAAI,UAAU;AAAA,YACd,QAAQ;AAAA,YACR,GAAI,gBAAgB,CAAC;AAAA,UACvB,GAAG;AAAA,YACD,cAAc,UAAU,gCAAgC;AAAA,UAC1D,CAAC;AAAA,QACH;AAAA,QACA,SAAS;AAAA,UACP,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,YAAY,UAAU;AAAA,UACtB;AAAA,QACF;AAAA,QACA,iBAAiB,EAAE,IAAI,UAAU,IAAI,QAAQ,YAAY,GAAI,gBAAgB,CAAC,EAAG;AAAA,MACnF,CAAC;AACD,YAAM,UAAU,kCAAkC,GAAG,SAAS;AAC9D,gBAAU;AACV,aAAO;AAAA,IACT,SAAS,OAAO;AACd,YAAM,UAAU,mBAAmB,KAAK;AACxC,UAAI,QAAQ,SAAS,GAAG;AACtB,uBAAe,OAAO;AACtB,eAAO;AAAA,MACT;AACA,UAAI,8BAA8B,KAAK,GAAG;AACxC,eAAO;AAAA,MACT;AACA,YAAM,UAAU,gCAAgC,GAAG,OAAO;AAC1D,aAAO;AAAA,IACT;AAAA,EACF,GAAG,CAAC,mBAAmB,WAAW,mBAAmB,aAAa,UAAU,IAAI,UAAU,WAAW,SAAS,CAAC;AAE/G,QAAM,wBAAwB,MAAM,YAAY,OAAO,eAAoC;AACzF,QAAI,UAAU,WAAW,eAAe,eAAe,aAAa;AAClE,6BAAuB,IAAI;AAC3B;AAAA,IACF;AACA,UAAM,YAAY,MAAM,QAAQ;AAAA,MAC9B,OAAO,UAAU,iBAAiB,UAAU,CAAC;AAAA,MAC7C,MAAM,UAAU,gBAAgB,UAAU,CAAC;AAAA,MAC3C,SAAS,eAAe,cAAc,eAAe,cAAc,gBAAgB;AAAA,IACrF,CAAC;AACD,QAAI,CAAC,UAAW;AAChB,UAAM,kBAAkB,UAAU;AAAA,EACpC,GAAG,CAAC,SAAS,mBAAmB,UAAU,QAAQ,SAAS,CAAC;AAE5D,QAAM,kBAAkB,MAAM,QAAqB,MAAM;AAAA,IACvD;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,UAAU,sCAAsC;AAAA,MACvD,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,UAAU,yCAAyC;AAAA,MAC1D,MAAM;AAAA,MACN,UAAU;AAAA,IACZ;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,UAAU,wCAAwC;AAAA,MACzD,MAAM;AAAA,MACN,SAAS,oBAAI,KAAK;AAAA,IACpB;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AAEd,QAAM,kBAAkB,MAAM,QAAyB,MAAM;AAAA,IAC3D;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,UAAU,wCAAwC;AAAA,MACzD,QAAQ;AAAA,MACR,QAAQ,CAAC,mBAAmB,sBAAsB,mBAAmB;AAAA,IACvE;AAAA,EACF,GAAG,CAAC,SAAS,CAAC;AAEd,SACE,qBAAC,aAAQ,WAAU,yDACjB;AAAA,yBAAC,SAAI,WAAU,qEACb;AAAA,2BAAC,SAAI,WAAU,aACb;AAAA,6BAAC,SAAI,WAAU,qCACb;AAAA,8BAAC,UAAK,WAAU,uBAAuB,oBAAU,8BAA8B,GAAE;AAAA,UACjF,oBAAC,eAAY,SAAS,mBAAmB,UAAU,MAAM,GAAG,KAAG,MAC5D,oBAAU,wBAAwB,UAAU,MAAM,EAAE,GACvD;AAAA,UACC,UAAU,WAAW,eAAe,WACnC,kBACE,oBAAC,eAAY,SAAQ,QAClB,oBAAU,uCAAuC,eAAe,gBAAgB,CAAC,GACpF,IAEA,oBAAC,eAAY,SAAQ,WAClB,oBAAU,kCAAkC,GAC/C,IAEA;AAAA,UACH,iBACC,oBAAC,eAAY,SAAQ,WAClB,oBAAU,8BAA8B,GAC3C,IACE;AAAA,WACN;AAAA,QACC,cACC,oBAAC,OAAE,WAAU,iCACV,oBAAU,8BAA8B,EAAE,MAAM,YAAY,mBAAmB,UAAU,MAAS,EAAE,CAAC,GACxG,IACE;AAAA,SACN;AAAA,MACA,oBAAC,SAAI,WAAU,qCACZ,qCAA2B,UAAU,MAAM,EAAE,IAAI,CAAC,eACjD;AAAA,QAAC;AAAA;AAAA,UAEC,MAAK;AAAA,UACL,SAAS,eAAe,cAAc,eAAe,cAAc,YAAY;AAAA,UAC/E,SAAS,MAAM,KAAK,sBAAsB,UAAU;AAAA,UAEpD;AAAA,gCAAC,gBAAa,WAAU,UAAS,eAAY,QAAO;AAAA,YACnD,UAAU,oBAAoB,UAAU,CAAC;AAAA;AAAA;AAAA,QANrC;AAAA,MAOP,CACD,GACH;AAAA,OACF;AAAA,IAEC,YAAY,SAAS,IACpB,qBAAC,SAAM,QAAO,WAAU,OAAM,WAC5B;AAAA,0BAAC,cAAY,oBAAU,iCAAiC,GAAE;AAAA,MAC1D,oBAAC,SAAI,WAAU,qBACb,8BAAC,QAAG,WAAU,4BACX,sBAAY,IAAI,CAAC,WAChB,oBAAC,QAAiB,oBAAU,MAAM,KAAzB,MAA2B,CACrC,GACH,GACF;AAAA,OACF,IACE;AAAA,IAEJ,oBAAC,UAAO,MAAM,qBAAqB,cAAc,wBAC/C,+BAAC,iBAAc,MAAK,MAClB;AAAA,0BAAC,gBACC,8BAAC,eAAa,oBAAU,sCAAsC,GAAE,GAClE;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,UAAQ;AAAA,UACR,OAAO,UAAU,sCAAsC;AAAA,UACvD,aAAa,UAAU,uCAAuC;AAAA,UAC9D,QAAQ;AAAA,UACR,QAAQ;AAAA,UACR,eAAe;AAAA,YACb,iBAAiB,UAAU,mBAAmB;AAAA,YAC9C,oBAAoB,UAAU,sBAAsB;AAAA,YACpD,mBAAmB,UAAU,oBACzB,qBAAqB,IAAI,KAAK,UAAU,iBAAiB,CAAC,IAC1D,qBAAqB,oBAAI,KAAK,CAAC;AAAA,UACrC;AAAA,UACA,UAAU,OAAO,WAAW;AAC1B,kBAAM,kBAAkB,aAAa,OAAO,eAAe;AAC3D,gBAAI,CAAC,iBAAiB;AACpB,oBAAM,UAAU,UAAU,wDAAwD;AAClF,oBAAM,oBAAoB,SAAS,EAAE,iBAAiB,QAAQ,CAAC;AAAA,YACjE;AACA,kBAAM,qBAAqB,aAAa,OAAO,kBAAkB;AACjE,gBAAI,CAAC,oBAAoB;AACvB,oBAAM,UAAU,UAAU,2DAA2D;AACrF,oBAAM,oBAAoB,SAAS,EAAE,oBAAoB,QAAQ,CAAC;AAAA,YACpE;AACA,kBAAM,eAAe,aAAa,OAAO,iBAAiB;AAC1D,kBAAMA,YAAW,eAAe,IAAI,KAAK,YAAY,IAAI,oBAAI,KAAK;AAClE,gBAAI,OAAO,MAAMA,UAAS,QAAQ,CAAC,KAAKA,UAAS,QAAQ,IAAI,KAAK,IAAI,GAAG;AACvE,oBAAM,UAAU,UAAU,yDAAyD;AACnF,oBAAM,oBAAoB,SAAS,EAAE,mBAAmB,QAAQ,CAAC;AAAA,YACnE;AACA,kBAAM,KAAK,MAAM,kBAAkB,aAAa;AAAA,cAC9C;AAAA,cACA;AAAA,cACA,mBAAmBA,UAAS,YAAY;AAAA,YAC1C,CAAC;AACD,gBAAI,CAAC,IAAI;AACP,oBAAM,oBAAoB,UAAU,kCAAkC,CAAC;AAAA,YACzE;AACA,mCAAuB,KAAK;AAAA,UAC9B;AAAA;AAAA,MACF;AAAA,OACF,GACF;AAAA,IACC;AAAA,KACH;AAEJ;AAEA,IAAO,gCAAQ;",
6
+ "names": ["issuedAt"]
7
+ }
@@ -0,0 +1,56 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import * as React from "react";
4
+ import { CheckCircle2, CircleDashed } from "lucide-react";
5
+ import { useT } from "@open-mercato/shared/lib/i18n/context";
6
+ import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
7
+ import { Alert, AlertTitle } from "@open-mercato/ui/primitives/alert";
8
+ function StatementReadinessChecklist({
9
+ statementId,
10
+ status,
11
+ updatedAt
12
+ }) {
13
+ const translate = useT();
14
+ const [readiness, setReadiness] = React.useState(null);
15
+ React.useEffect(() => {
16
+ if (status !== "draft") {
17
+ setReadiness(null);
18
+ return;
19
+ }
20
+ let cancelled = false;
21
+ async function loadReadiness() {
22
+ const call = await apiCall(
23
+ `/api/eudr/statements/${encodeURIComponent(statementId)}/readiness`,
24
+ void 0,
25
+ { fallback: null }
26
+ );
27
+ if (cancelled || !call.ok || !call.result) return;
28
+ const reasons = Array.isArray(call.result.reasons) ? call.result.reasons.filter((reason) => typeof reason === "string" && reason.length > 0) : [];
29
+ setReadiness({ allowed: call.result.allowed === true, reasons });
30
+ }
31
+ void loadReadiness();
32
+ return () => {
33
+ cancelled = true;
34
+ };
35
+ }, [statementId, status, updatedAt]);
36
+ if (status !== "draft" || readiness === null) return null;
37
+ if (readiness.allowed) {
38
+ return /* @__PURE__ */ jsx(Alert, { status: "success", style: "lighter", children: /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm leading-5", children: [
39
+ /* @__PURE__ */ jsx(CheckCircle2, { className: "size-4 shrink-0", "aria-hidden": "true" }),
40
+ translate("eudr.lifecycle.readinessReady")
41
+ ] }) });
42
+ }
43
+ return /* @__PURE__ */ jsxs(Alert, { status: "information", style: "lighter", children: [
44
+ /* @__PURE__ */ jsx(AlertTitle, { children: translate("eudr.lifecycle.readinessTitle") }),
45
+ /* @__PURE__ */ jsx("ul", { className: "space-y-1 text-sm leading-5", children: readiness.reasons.map((reason) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2", children: [
46
+ /* @__PURE__ */ jsx(CircleDashed, { className: "mt-0.5 size-4 shrink-0", "aria-hidden": "true" }),
47
+ /* @__PURE__ */ jsx("span", { children: translate(reason) })
48
+ ] }, reason)) })
49
+ ] });
50
+ }
51
+ var StatementReadinessChecklist_default = StatementReadinessChecklist;
52
+ export {
53
+ StatementReadinessChecklist,
54
+ StatementReadinessChecklist_default as default
55
+ };
56
+ //# sourceMappingURL=StatementReadinessChecklist.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/eudr/components/StatementReadinessChecklist.tsx"],
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { CheckCircle2, CircleDashed } from 'lucide-react'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { Alert, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport type { EudrStatementStatus } from '../data/validators'\n\ntype ReadinessResponse = {\n status?: string\n allowed?: boolean\n reasons?: string[]\n}\n\nexport type StatementReadinessChecklistProps = {\n statementId: string\n status: EudrStatementStatus\n updatedAt: string\n}\n\nexport function StatementReadinessChecklist({\n statementId,\n status,\n updatedAt,\n}: StatementReadinessChecklistProps) {\n const translate = useT()\n const [readiness, setReadiness] = React.useState<{ allowed: boolean; reasons: string[] } | null>(null)\n\n React.useEffect(() => {\n if (status !== 'draft') {\n setReadiness(null)\n return\n }\n let cancelled = false\n async function loadReadiness() {\n const call = await apiCall<ReadinessResponse>(\n `/api/eudr/statements/${encodeURIComponent(statementId)}/readiness`,\n undefined,\n { fallback: null },\n )\n if (cancelled || !call.ok || !call.result) return\n const reasons = Array.isArray(call.result.reasons)\n ? call.result.reasons.filter((reason): reason is string => typeof reason === 'string' && reason.length > 0)\n : []\n setReadiness({ allowed: call.result.allowed === true, reasons })\n }\n void loadReadiness()\n return () => {\n cancelled = true\n }\n }, [statementId, status, updatedAt])\n\n if (status !== 'draft' || readiness === null) return null\n\n if (readiness.allowed) {\n return (\n <Alert status=\"success\" style=\"lighter\">\n <div className=\"flex items-center gap-2 text-sm leading-5\">\n <CheckCircle2 className=\"size-4 shrink-0\" aria-hidden=\"true\" />\n {translate('eudr.lifecycle.readinessReady')}\n </div>\n </Alert>\n )\n }\n\n return (\n <Alert status=\"information\" style=\"lighter\">\n <AlertTitle>{translate('eudr.lifecycle.readinessTitle')}</AlertTitle>\n <ul className=\"space-y-1 text-sm leading-5\">\n {readiness.reasons.map((reason) => (\n <li key={reason} className=\"flex items-start gap-2\">\n <CircleDashed className=\"mt-0.5 size-4 shrink-0\" aria-hidden=\"true\" />\n <span>{translate(reason)}</span>\n </li>\n ))}\n </ul>\n </Alert>\n )\n}\n\nexport default StatementReadinessChecklist\n"],
5
+ "mappings": ";AA0DQ,SACE,KADF;AAxDR,YAAY,WAAW;AACvB,SAAS,cAAc,oBAAoB;AAC3C,SAAS,YAAY;AACrB,SAAS,eAAe;AACxB,SAAS,OAAO,kBAAkB;AAe3B,SAAS,4BAA4B;AAAA,EAC1C;AAAA,EACA;AAAA,EACA;AACF,GAAqC;AACnC,QAAM,YAAY,KAAK;AACvB,QAAM,CAAC,WAAW,YAAY,IAAI,MAAM,SAAyD,IAAI;AAErG,QAAM,UAAU,MAAM;AACpB,QAAI,WAAW,SAAS;AACtB,mBAAa,IAAI;AACjB;AAAA,IACF;AACA,QAAI,YAAY;AAChB,mBAAe,gBAAgB;AAC7B,YAAM,OAAO,MAAM;AAAA,QACjB,wBAAwB,mBAAmB,WAAW,CAAC;AAAA,QACvD;AAAA,QACA,EAAE,UAAU,KAAK;AAAA,MACnB;AACA,UAAI,aAAa,CAAC,KAAK,MAAM,CAAC,KAAK,OAAQ;AAC3C,YAAM,UAAU,MAAM,QAAQ,KAAK,OAAO,OAAO,IAC7C,KAAK,OAAO,QAAQ,OAAO,CAAC,WAA6B,OAAO,WAAW,YAAY,OAAO,SAAS,CAAC,IACxG,CAAC;AACL,mBAAa,EAAE,SAAS,KAAK,OAAO,YAAY,MAAM,QAAQ,CAAC;AAAA,IACjE;AACA,SAAK,cAAc;AACnB,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,aAAa,QAAQ,SAAS,CAAC;AAEnC,MAAI,WAAW,WAAW,cAAc,KAAM,QAAO;AAErD,MAAI,UAAU,SAAS;AACrB,WACE,oBAAC,SAAM,QAAO,WAAU,OAAM,WAC5B,+BAAC,SAAI,WAAU,6CACb;AAAA,0BAAC,gBAAa,WAAU,mBAAkB,eAAY,QAAO;AAAA,MAC5D,UAAU,+BAA+B;AAAA,OAC5C,GACF;AAAA,EAEJ;AAEA,SACE,qBAAC,SAAM,QAAO,eAAc,OAAM,WAChC;AAAA,wBAAC,cAAY,oBAAU,+BAA+B,GAAE;AAAA,IACxD,oBAAC,QAAG,WAAU,+BACX,oBAAU,QAAQ,IAAI,CAAC,WACtB,qBAAC,QAAgB,WAAU,0BACzB;AAAA,0BAAC,gBAAa,WAAU,0BAAyB,eAAY,QAAO;AAAA,MACpE,oBAAC,UAAM,oBAAU,MAAM,GAAE;AAAA,SAFlB,MAGT,CACD,GACH;AAAA,KACF;AAEJ;AAEA,IAAO,sCAAQ;",
6
+ "names": []
7
+ }