@open-mercato/core 0.5.1-develop.2953.6647bb2c43 → 0.5.1-develop.2954.610bab2d08

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 (226) hide show
  1. package/dist/helpers/integration/salesUi.js +25 -23
  2. package/dist/helpers/integration/salesUi.js.map +2 -2
  3. package/dist/modules/api_docs/frontend/docs/api/Explorer.js +24 -24
  4. package/dist/modules/api_docs/frontend/docs/api/Explorer.js.map +2 -2
  5. package/dist/modules/attachments/components/AttachmentPartitionSettings.js +15 -7
  6. package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
  7. package/dist/modules/attachments/fields/attachment.js +4 -6
  8. package/dist/modules/attachments/fields/attachment.js.map +2 -2
  9. package/dist/modules/auth/backend/users/create/page.js +26 -26
  10. package/dist/modules/auth/backend/users/create/page.js.map +2 -2
  11. package/dist/modules/business_rules/components/ActionRow.js +36 -25
  12. package/dist/modules/business_rules/components/ActionRow.js.map +2 -2
  13. package/dist/modules/business_rules/components/ConditionGroup.js +14 -5
  14. package/dist/modules/business_rules/components/ConditionGroup.js.map +2 -2
  15. package/dist/modules/business_rules/components/ConditionRow.js +19 -10
  16. package/dist/modules/business_rules/components/ConditionRow.js.map +2 -2
  17. package/dist/modules/business_rules/components/RuleSetMembers.js +16 -10
  18. package/dist/modules/business_rules/components/RuleSetMembers.js.map +2 -2
  19. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +30 -34
  20. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  21. package/dist/modules/catalog/backend/catalog/products/create/page.js +220 -223
  22. package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
  23. package/dist/modules/catalog/components/PriceKindSettings.js +20 -19
  24. package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
  25. package/dist/modules/catalog/components/products/ProductUomSection.js +42 -37
  26. package/dist/modules/catalog/components/products/ProductUomSection.js.map +2 -2
  27. package/dist/modules/catalog/components/products/VariantBuilder.js +22 -18
  28. package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
  29. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +18 -26
  30. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  31. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +4 -6
  32. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  33. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +5 -4
  34. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
  35. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +19 -7
  36. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
  37. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +24 -21
  38. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  39. package/dist/modules/customers/components/AddressEditor.js +24 -7
  40. package/dist/modules/customers/components/AddressEditor.js.map +2 -2
  41. package/dist/modules/customers/components/AddressFormatSettings.js +35 -25
  42. package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
  43. package/dist/modules/customers/components/detail/ActivityForm.js +20 -12
  44. package/dist/modules/customers/components/detail/ActivityForm.js.map +2 -2
  45. package/dist/modules/customers/components/detail/AnnualRevenueField.js +2 -2
  46. package/dist/modules/customers/components/detail/AnnualRevenueField.js.map +2 -2
  47. package/dist/modules/customers/components/detail/DealForm.js +19 -14
  48. package/dist/modules/customers/components/detail/DealForm.js.map +2 -2
  49. package/dist/modules/customers/components/formConfig.js +16 -12
  50. package/dist/modules/customers/components/formConfig.js.map +2 -2
  51. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js +3 -2
  52. package/dist/modules/customers/widgets/dashboard/customer-todos/widget.client.js.map +2 -2
  53. package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js +18 -10
  54. package/dist/modules/customers/widgets/dashboard/new-customers/widget.client.js.map +2 -2
  55. package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js +3 -2
  56. package/dist/modules/customers/widgets/dashboard/new-deals/widget.client.js.map +2 -2
  57. package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js +3 -2
  58. package/dist/modules/customers/widgets/dashboard/next-interactions/widget.client.js.map +2 -2
  59. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js +27 -28
  60. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
  61. package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js +14 -6
  62. package/dist/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.js.map +2 -2
  63. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js +14 -6
  64. package/dist/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.js.map +2 -2
  65. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js +3 -2
  66. package/dist/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.js.map +2 -2
  67. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js +3 -2
  68. package/dist/modules/dashboards/widgets/dashboard/top-customers/widget.client.js.map +2 -2
  69. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js +17 -8
  70. package/dist/modules/dashboards/widgets/dashboard/top-products/widget.client.js.map +2 -2
  71. package/dist/modules/data_sync/backend/data-sync/page.js +40 -23
  72. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  73. package/dist/modules/data_sync/components/IntegrationScheduleTab.js +15 -6
  74. package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
  75. package/dist/modules/dictionaries/components/AppearanceSelector.js +4 -4
  76. package/dist/modules/dictionaries/components/AppearanceSelector.js.map +2 -2
  77. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +4 -5
  78. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
  79. package/dist/modules/dictionaries/components/DictionaryEntrySelect.js +22 -14
  80. package/dist/modules/dictionaries/components/DictionaryEntrySelect.js.map +2 -2
  81. package/dist/modules/dictionaries/fields/dictionary.js +18 -13
  82. package/dist/modules/dictionaries/fields/dictionary.js.map +2 -2
  83. package/dist/modules/entities/components/EncryptionManager.js +23 -19
  84. package/dist/modules/entities/components/EncryptionManager.js.map +2 -2
  85. package/dist/modules/feature_toggles/components/formConfig.js +17 -9
  86. package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
  87. package/dist/modules/feature_toggles/components/overrideFormConfig.js +17 -9
  88. package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
  89. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +15 -8
  90. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
  91. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +37 -22
  92. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
  93. package/dist/modules/integrations/backend/integrations/[id]/page.js +22 -17
  94. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  95. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +12 -6
  96. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  97. package/dist/modules/planner/components/AvailabilityRulesEditor.js +19 -12
  98. package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
  99. package/dist/modules/resources/components/ResourceCrudForm.js +15 -10
  100. package/dist/modules/resources/components/ResourceCrudForm.js.map +3 -3
  101. package/dist/modules/sales/backend/sales/documents/[id]/page.js +15 -18
  102. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  103. package/dist/modules/sales/components/ProviderFieldInput.js +23 -20
  104. package/dist/modules/sales/components/ProviderFieldInput.js.map +2 -2
  105. package/dist/modules/sales/components/ShippingMethodsSettings.js +25 -17
  106. package/dist/modules/sales/components/ShippingMethodsSettings.js.map +3 -3
  107. package/dist/modules/sales/components/channels/ChannelOfferForm.js +35 -42
  108. package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
  109. package/dist/modules/sales/components/documents/AddressesSection.js +87 -90
  110. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  111. package/dist/modules/sales/components/documents/AdjustmentDialog.js +17 -6
  112. package/dist/modules/sales/components/documents/AdjustmentDialog.js.map +3 -3
  113. package/dist/modules/sales/components/documents/LineItemDialog.js +42 -25
  114. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  115. package/dist/modules/sales/components/documents/SalesDocumentForm.js +96 -87
  116. package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
  117. package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js +20 -11
  118. package/dist/modules/sales/widgets/dashboard/new-orders/widget.client.js.map +2 -2
  119. package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js +20 -11
  120. package/dist/modules/sales/widgets/dashboard/new-quotes/widget.client.js.map +2 -2
  121. package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js +36 -22
  122. package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js.map +2 -2
  123. package/dist/modules/staff/components/TeamMemberForm.js +14 -9
  124. package/dist/modules/staff/components/TeamMemberForm.js.map +3 -3
  125. package/dist/modules/workflows/backend/tasks/[id]/page.js +42 -21
  126. package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
  127. package/dist/modules/workflows/components/ActivitiesEditor.js +14 -6
  128. package/dist/modules/workflows/components/ActivitiesEditor.js.map +3 -3
  129. package/dist/modules/workflows/components/DefinitionTriggersEditor.js +25 -17
  130. package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +3 -3
  131. package/dist/modules/workflows/components/EdgeEditDialog.js +48 -45
  132. package/dist/modules/workflows/components/EdgeEditDialog.js.map +2 -2
  133. package/dist/modules/workflows/components/NodeEditDialog.js +90 -90
  134. package/dist/modules/workflows/components/NodeEditDialog.js.map +2 -2
  135. package/dist/modules/workflows/components/StepsEditor.js +14 -6
  136. package/dist/modules/workflows/components/StepsEditor.js.map +3 -3
  137. package/dist/modules/workflows/components/TransitionsEditor.js +31 -26
  138. package/dist/modules/workflows/components/TransitionsEditor.js.map +3 -3
  139. package/dist/modules/workflows/components/fields/ActivityArrayEditor.js +19 -11
  140. package/dist/modules/workflows/components/fields/ActivityArrayEditor.js.map +3 -3
  141. package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js +12 -14
  142. package/dist/modules/workflows/components/fields/BusinessRuleConditionsEditor.js.map +2 -2
  143. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js +24 -16
  144. package/dist/modules/workflows/components/fields/FormFieldArrayEditor.js.map +3 -3
  145. package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js +12 -13
  146. package/dist/modules/workflows/components/fields/StartPreConditionsEditor.js.map +2 -2
  147. package/dist/modules/workflows/components/mobile/MobileTaskForm.js +12 -8
  148. package/dist/modules/workflows/components/mobile/MobileTaskForm.js.map +2 -2
  149. package/dist/modules/workflows/frontend/checkout-demo/page.js +43 -46
  150. package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
  151. package/package.json +3 -3
  152. package/src/helpers/integration/salesUi.ts +40 -30
  153. package/src/modules/api_docs/frontend/docs/api/Explorer.tsx +25 -19
  154. package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +21 -11
  155. package/src/modules/attachments/fields/attachment.tsx +4 -6
  156. package/src/modules/auth/backend/users/create/page.tsx +16 -20
  157. package/src/modules/business_rules/components/ActionRow.tsx +51 -32
  158. package/src/modules/business_rules/components/ConditionGroup.tsx +20 -9
  159. package/src/modules/business_rules/components/ConditionRow.tsx +24 -15
  160. package/src/modules/business_rules/components/RuleSetMembers.tsx +23 -13
  161. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +47 -53
  162. package/src/modules/catalog/backend/catalog/products/create/page.tsx +84 -87
  163. package/src/modules/catalog/components/PriceKindSettings.tsx +9 -9
  164. package/src/modules/catalog/components/products/ProductUomSection.tsx +85 -83
  165. package/src/modules/catalog/components/products/VariantBuilder.tsx +49 -33
  166. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +12 -27
  167. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +4 -6
  168. package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +5 -4
  169. package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +28 -15
  170. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +37 -26
  171. package/src/modules/customers/components/AddressEditor.tsx +30 -16
  172. package/src/modules/customers/components/AddressFormatSettings.tsx +25 -19
  173. package/src/modules/customers/components/detail/ActivityForm.tsx +35 -23
  174. package/src/modules/customers/components/detail/AnnualRevenueField.tsx +2 -2
  175. package/src/modules/customers/components/detail/DealForm.tsx +33 -20
  176. package/src/modules/customers/components/formConfig.tsx +25 -17
  177. package/src/modules/customers/widgets/dashboard/customer-todos/widget.client.tsx +3 -2
  178. package/src/modules/customers/widgets/dashboard/new-customers/widget.client.tsx +21 -11
  179. package/src/modules/customers/widgets/dashboard/new-deals/widget.client.tsx +3 -2
  180. package/src/modules/customers/widgets/dashboard/next-interactions/widget.client.tsx +3 -2
  181. package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +17 -22
  182. package/src/modules/dashboards/widgets/dashboard/orders-by-status/widget.client.tsx +17 -7
  183. package/src/modules/dashboards/widgets/dashboard/revenue-trend/widget.client.tsx +20 -10
  184. package/src/modules/dashboards/widgets/dashboard/sales-by-region/widget.client.tsx +3 -2
  185. package/src/modules/dashboards/widgets/dashboard/top-customers/widget.client.tsx +3 -2
  186. package/src/modules/dashboards/widgets/dashboard/top-products/widget.client.tsx +20 -9
  187. package/src/modules/data_sync/backend/data-sync/page.tsx +64 -38
  188. package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +18 -7
  189. package/src/modules/dictionaries/components/AppearanceSelector.tsx +4 -4
  190. package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +3 -4
  191. package/src/modules/dictionaries/components/DictionaryEntrySelect.tsx +27 -21
  192. package/src/modules/dictionaries/fields/dictionary.tsx +36 -23
  193. package/src/modules/entities/components/EncryptionManager.tsx +49 -33
  194. package/src/modules/feature_toggles/components/formConfig.tsx +20 -10
  195. package/src/modules/feature_toggles/components/overrideFormConfig.tsx +20 -10
  196. package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +19 -10
  197. package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +49 -26
  198. package/src/modules/integrations/backend/integrations/[id]/page.tsx +20 -11
  199. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +19 -9
  200. package/src/modules/planner/components/AvailabilityRulesEditor.tsx +34 -21
  201. package/src/modules/resources/components/ResourceCrudForm.tsx +24 -15
  202. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +12 -15
  203. package/src/modules/sales/components/ProviderFieldInput.tsx +26 -17
  204. package/src/modules/sales/components/ShippingMethodsSettings.tsx +28 -20
  205. package/src/modules/sales/components/channels/ChannelOfferForm.tsx +51 -46
  206. package/src/modules/sales/components/documents/AddressesSection.tsx +78 -76
  207. package/src/modules/sales/components/documents/AdjustmentDialog.tsx +27 -15
  208. package/src/modules/sales/components/documents/LineItemDialog.tsx +69 -51
  209. package/src/modules/sales/components/documents/SalesDocumentForm.tsx +98 -87
  210. package/src/modules/sales/widgets/dashboard/new-orders/widget.client.tsx +23 -12
  211. package/src/modules/sales/widgets/dashboard/new-quotes/widget.client.tsx +23 -12
  212. package/src/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.tsx +35 -19
  213. package/src/modules/staff/components/TeamMemberForm.tsx +23 -14
  214. package/src/modules/workflows/backend/tasks/[id]/page.tsx +51 -23
  215. package/src/modules/workflows/components/ActivitiesEditor.tsx +20 -10
  216. package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +28 -18
  217. package/src/modules/workflows/components/EdgeEditDialog.tsx +51 -40
  218. package/src/modules/workflows/components/NodeEditDialog.tsx +81 -77
  219. package/src/modules/workflows/components/StepsEditor.tsx +20 -10
  220. package/src/modules/workflows/components/TransitionsEditor.tsx +61 -44
  221. package/src/modules/workflows/components/fields/ActivityArrayEditor.tsx +22 -12
  222. package/src/modules/workflows/components/fields/BusinessRuleConditionsEditor.tsx +9 -13
  223. package/src/modules/workflows/components/fields/FormFieldArrayEditor.tsx +27 -17
  224. package/src/modules/workflows/components/fields/StartPreConditionsEditor.tsx +9 -12
  225. package/src/modules/workflows/components/mobile/MobileTaskForm.tsx +19 -11
  226. package/src/modules/workflows/frontend/checkout-demo/page.tsx +71 -60
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/sales/widgets/dashboard/new-orders/widget.client.tsx"],
4
- "sourcesContent": ["\"use client\"\r\n\r\nimport * as React from 'react'\r\nimport Link from 'next/link'\r\nimport type { DashboardWidgetComponentProps } from '@open-mercato/shared/modules/dashboard/widgets'\r\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\r\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\r\nimport { Badge } from '@open-mercato/ui/primitives/badge'\r\nimport { formatRelativeTime } from '@open-mercato/shared/lib/time'\r\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\r\nimport { DEFAULT_SETTINGS, hydrateSalesNewOrdersSettings, type DatePeriodOption, type SalesNewOrdersSettings } from './config'\r\nimport { readString, toDateInputValue, openNativeDatePicker, formatAmount } from '../shared'\r\n\r\ntype NewOrderItem = {\r\n id: string\r\n orderNumber: string\r\n status: string | null\r\n customerName: string | null\r\n customerEntityId: string | null\r\n netAmount: string\r\n grossAmount: string\r\n currency: string | null\r\n createdAt: string\r\n}\r\n\r\ntype NewOrdersApiPayload = {\r\n items?: unknown[]\r\n error?: string\r\n}\r\n\r\nfunction parseNewOrderItems(payload: NewOrdersApiPayload | null): NewOrderItem[] {\r\n const rawItems = Array.isArray(payload?.items) ? payload?.items : []\r\n return rawItems\r\n .map((item) => {\r\n if (!item || typeof item !== 'object') return null\r\n const data = item as Record<string, unknown>\r\n const id = readString(data.id)\r\n const orderNumber = readString(data.orderNumber)\r\n const createdAt = readString(data.createdAt)\r\n if (!id || !orderNumber || !createdAt) return null\r\n return {\r\n id,\r\n orderNumber,\r\n status: readString(data.status),\r\n customerName: readString(data.customerName),\r\n customerEntityId: readString(data.customerEntityId),\r\n netAmount: readString(data.netAmount) ?? '0',\r\n grossAmount: readString(data.grossAmount) ?? '0',\r\n currency: readString(data.currency),\r\n createdAt,\r\n }\r\n })\r\n .filter((item): item is NewOrderItem => !!item)\r\n}\r\n\r\nasync function loadNewOrders(settings: SalesNewOrdersSettings): Promise<NewOrderItem[]> {\r\n const params = new URLSearchParams({\r\n limit: String(settings.pageSize),\r\n datePeriod: settings.datePeriod,\r\n })\r\n if (settings.datePeriod === 'custom') {\r\n if (settings.customFrom) params.set('customFrom', settings.customFrom)\r\n if (settings.customTo) params.set('customTo', settings.customTo)\r\n }\r\n\r\n const call = await apiCall<NewOrdersApiPayload>(`/api/sales/dashboard/widgets/new-orders?${params.toString()}`)\r\n if (!call.ok) {\r\n const message =\r\n typeof (call.result as Record<string, unknown> | null)?.error === 'string'\r\n ? ((call.result as Record<string, unknown>).error as string)\r\n : `Request failed with status ${call.status}`\r\n throw new Error(message)\r\n }\r\n return parseNewOrderItems(call.result ?? null)\r\n}\r\n\r\nfunction resolveDetailHref(item: NewOrderItem): string | null {\r\n return item.id ? `/backend/sales/orders/${encodeURIComponent(item.id)}` : null\r\n}\r\n\r\n\r\nconst SalesNewOrdersWidget: React.FC<DashboardWidgetComponentProps<SalesNewOrdersSettings>> = ({\r\n mode,\r\n settings = DEFAULT_SETTINGS,\r\n onSettingsChange,\r\n refreshToken,\r\n onRefreshStateChange,\r\n}) => {\r\n const translate = useT()\r\n const hydrated = React.useMemo(() => hydrateSalesNewOrdersSettings(settings), [settings])\r\n const [items, setItems] = React.useState<NewOrderItem[]>([])\r\n const [loading, setLoading] = React.useState(true)\r\n const [error, setError] = React.useState<string | null>(null)\r\n const [locale, setLocale] = React.useState<string | undefined>(undefined)\r\n\r\n React.useEffect(() => {\r\n if (typeof navigator !== 'undefined') {\r\n setLocale(navigator.language)\r\n }\r\n }, [])\r\n\r\n const refresh = React.useCallback(async () => {\r\n onRefreshStateChange?.(true)\r\n setLoading(true)\r\n setError(null)\r\n try {\r\n const data = await loadNewOrders(hydrated)\r\n setItems(data)\r\n } catch (err) {\r\n console.error('Failed to load new orders widget data', err)\r\n setError(translate('sales.widgets.newOrders.error', 'Failed to load orders'))\r\n } finally {\r\n setLoading(false)\r\n onRefreshStateChange?.(false)\r\n }\r\n }, [hydrated, onRefreshStateChange, translate])\r\n\r\n React.useEffect(() => {\r\n refresh().catch(() => {})\r\n }, [refresh, refreshToken])\r\n\r\n if (mode === 'settings') {\r\n return (\r\n <div className=\"space-y-4 text-sm\">\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-orders-page-size\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newOrders.settings.pageSize', 'Number of Orders')}\r\n </label>\r\n <input\r\n id=\"sales-new-orders-page-size\"\r\n type=\"number\"\r\n min={1}\r\n max={20}\r\n className=\"w-24 rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n value={hydrated.pageSize}\r\n onChange={(event) => {\r\n const next = Number(event.target.value)\r\n if (!Number.isFinite(next)) return\r\n const clamped = Math.min(20, Math.max(1, Math.floor(next)))\r\n onSettingsChange?.({ ...hydrated, pageSize: clamped })\r\n }}\r\n />\r\n </div>\r\n\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-orders-date-period\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newOrders.settings.datePeriod', 'Date Period')}\r\n </label>\r\n <select\r\n id=\"sales-new-orders-date-period\"\r\n value={hydrated.datePeriod}\r\n onChange={(event) => {\r\n onSettingsChange?.({ ...hydrated, datePeriod: event.target.value as DatePeriodOption })\r\n }}\r\n className=\"w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n >\r\n <option value=\"last24h\">{translate('sales.widgets.newOrders.settings.last24h', 'Last 24 hours')}</option>\r\n <option value=\"last7d\">{translate('sales.widgets.newOrders.settings.last7d', 'Last 7 days')}</option>\r\n <option value=\"last30d\">{translate('sales.widgets.newOrders.settings.last30d', 'Last 30 days')}</option>\r\n <option value=\"custom\">{translate('sales.widgets.newOrders.settings.custom', 'Custom range')}</option>\r\n </select>\r\n </div>\r\n\r\n {hydrated.datePeriod === 'custom' ? (\r\n <div className=\"grid gap-3\">\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-orders-custom-from\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newOrders.settings.customFrom', 'From')}\r\n </label>\r\n <input\r\n id=\"sales-new-orders-custom-from\"\r\n type=\"date\"\r\n value={toDateInputValue(hydrated.customFrom)}\r\n onChange={(event) => {\r\n onSettingsChange?.({ ...hydrated, customFrom: event.target.value })\r\n }}\r\n onFocus={openNativeDatePicker}\r\n onClick={openNativeDatePicker}\r\n className=\"w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n />\r\n </div>\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-orders-custom-to\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newOrders.settings.customTo', 'To')}\r\n </label>\r\n <input\r\n id=\"sales-new-orders-custom-to\"\r\n type=\"date\"\r\n value={toDateInputValue(hydrated.customTo)}\r\n onChange={(event) => {\r\n onSettingsChange?.({ ...hydrated, customTo: event.target.value })\r\n }}\r\n onFocus={openNativeDatePicker}\r\n onClick={openNativeDatePicker}\r\n className=\"w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n />\r\n </div>\r\n </div>\r\n ) : null}\r\n </div>\r\n )\r\n }\r\n\r\n if (error) {\r\n return <p className=\"text-sm text-destructive\">{error}</p>\r\n }\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex h-32 items-center justify-center\">\r\n <Spinner className=\"h-6 w-6 text-muted-foreground\" />\r\n </div>\r\n )\r\n }\r\n\r\n if (!items.length) {\r\n return <p className=\"text-sm text-muted-foreground\">{translate('sales.widgets.newOrders.empty', 'No orders found')}</p>\r\n }\r\n\r\n return (\r\n <ul className=\"space-y-3\">\r\n {items.map((item) => {\r\n const detailHref = resolveDetailHref(item)\r\n const amountLabel = formatAmount(item.grossAmount, item.currency, locale)\r\n const createdLabel = formatRelativeTime(item.createdAt) ?? ''\r\n return (\r\n <li key={item.id} className=\"rounded-md border p-3\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"space-y-1\">\r\n <div className=\"flex items-center gap-2\">\r\n {detailHref ? (\r\n <Link href={detailHref} className=\"text-sm font-semibold text-foreground hover:underline\">\r\n {item.orderNumber}\r\n </Link>\r\n ) : (\r\n <span className=\"text-sm font-semibold text-foreground\">{item.orderNumber}</span>\r\n )}\r\n {item.status ? (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {item.status}\r\n </Badge>\r\n ) : null}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {item.customerName ?? translate('sales.widgets.newOrders.noCustomer', 'No customer')}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground\">{createdLabel}</p>\r\n </div>\r\n <div className=\"text-right\">\r\n <p className=\"text-sm font-semibold\">{amountLabel}</p>\r\n </div>\r\n </div>\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n )\r\n}\r\n\r\nexport default SalesNewOrdersWidget\r\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\r\n\r\nimport * as React from 'react'\r\nimport Link from 'next/link'\r\nimport type { DashboardWidgetComponentProps } from '@open-mercato/shared/modules/dashboard/widgets'\r\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\r\nimport { Input } from '@open-mercato/ui/primitives/input'\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@open-mercato/ui/primitives/select'\r\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\r\nimport { Badge } from '@open-mercato/ui/primitives/badge'\r\nimport { formatRelativeTime } from '@open-mercato/shared/lib/time'\r\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\r\nimport { DEFAULT_SETTINGS, hydrateSalesNewOrdersSettings, type DatePeriodOption, type SalesNewOrdersSettings } from './config'\r\nimport { readString, toDateInputValue, openNativeDatePicker, formatAmount } from '../shared'\r\n\r\ntype NewOrderItem = {\r\n id: string\r\n orderNumber: string\r\n status: string | null\r\n customerName: string | null\r\n customerEntityId: string | null\r\n netAmount: string\r\n grossAmount: string\r\n currency: string | null\r\n createdAt: string\r\n}\r\n\r\ntype NewOrdersApiPayload = {\r\n items?: unknown[]\r\n error?: string\r\n}\r\n\r\nfunction parseNewOrderItems(payload: NewOrdersApiPayload | null): NewOrderItem[] {\r\n const rawItems = Array.isArray(payload?.items) ? payload?.items : []\r\n return rawItems\r\n .map((item) => {\r\n if (!item || typeof item !== 'object') return null\r\n const data = item as Record<string, unknown>\r\n const id = readString(data.id)\r\n const orderNumber = readString(data.orderNumber)\r\n const createdAt = readString(data.createdAt)\r\n if (!id || !orderNumber || !createdAt) return null\r\n return {\r\n id,\r\n orderNumber,\r\n status: readString(data.status),\r\n customerName: readString(data.customerName),\r\n customerEntityId: readString(data.customerEntityId),\r\n netAmount: readString(data.netAmount) ?? '0',\r\n grossAmount: readString(data.grossAmount) ?? '0',\r\n currency: readString(data.currency),\r\n createdAt,\r\n }\r\n })\r\n .filter((item): item is NewOrderItem => !!item)\r\n}\r\n\r\nasync function loadNewOrders(settings: SalesNewOrdersSettings): Promise<NewOrderItem[]> {\r\n const params = new URLSearchParams({\r\n limit: String(settings.pageSize),\r\n datePeriod: settings.datePeriod,\r\n })\r\n if (settings.datePeriod === 'custom') {\r\n if (settings.customFrom) params.set('customFrom', settings.customFrom)\r\n if (settings.customTo) params.set('customTo', settings.customTo)\r\n }\r\n\r\n const call = await apiCall<NewOrdersApiPayload>(`/api/sales/dashboard/widgets/new-orders?${params.toString()}`)\r\n if (!call.ok) {\r\n const message =\r\n typeof (call.result as Record<string, unknown> | null)?.error === 'string'\r\n ? ((call.result as Record<string, unknown>).error as string)\r\n : `Request failed with status ${call.status}`\r\n throw new Error(message)\r\n }\r\n return parseNewOrderItems(call.result ?? null)\r\n}\r\n\r\nfunction resolveDetailHref(item: NewOrderItem): string | null {\r\n return item.id ? `/backend/sales/orders/${encodeURIComponent(item.id)}` : null\r\n}\r\n\r\n\r\nconst SalesNewOrdersWidget: React.FC<DashboardWidgetComponentProps<SalesNewOrdersSettings>> = ({\r\n mode,\r\n settings = DEFAULT_SETTINGS,\r\n onSettingsChange,\r\n refreshToken,\r\n onRefreshStateChange,\r\n}) => {\r\n const translate = useT()\r\n const hydrated = React.useMemo(() => hydrateSalesNewOrdersSettings(settings), [settings])\r\n const [items, setItems] = React.useState<NewOrderItem[]>([])\r\n const [loading, setLoading] = React.useState(true)\r\n const [error, setError] = React.useState<string | null>(null)\r\n const [locale, setLocale] = React.useState<string | undefined>(undefined)\r\n\r\n React.useEffect(() => {\r\n if (typeof navigator !== 'undefined') {\r\n setLocale(navigator.language)\r\n }\r\n }, [])\r\n\r\n const refresh = React.useCallback(async () => {\r\n onRefreshStateChange?.(true)\r\n setLoading(true)\r\n setError(null)\r\n try {\r\n const data = await loadNewOrders(hydrated)\r\n setItems(data)\r\n } catch (err) {\r\n console.error('Failed to load new orders widget data', err)\r\n setError(translate('sales.widgets.newOrders.error', 'Failed to load orders'))\r\n } finally {\r\n setLoading(false)\r\n onRefreshStateChange?.(false)\r\n }\r\n }, [hydrated, onRefreshStateChange, translate])\r\n\r\n React.useEffect(() => {\r\n refresh().catch(() => {})\r\n }, [refresh, refreshToken])\r\n\r\n if (mode === 'settings') {\r\n return (\r\n <div className=\"space-y-4 text-sm\">\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-orders-page-size\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newOrders.settings.pageSize', 'Number of Orders')}\r\n </label>\r\n <Input\r\n id=\"sales-new-orders-page-size\"\r\n type=\"number\"\r\n min={1}\r\n max={20}\r\n className=\"w-24\"\r\n value={hydrated.pageSize}\r\n onChange={(event) => {\r\n const next = Number(event.target.value)\r\n if (!Number.isFinite(next)) return\r\n const clamped = Math.min(20, Math.max(1, Math.floor(next)))\r\n onSettingsChange?.({ ...hydrated, pageSize: clamped })\r\n }}\r\n />\r\n </div>\r\n\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-orders-date-period\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newOrders.settings.datePeriod', 'Date Period')}\r\n </label>\r\n <Select\r\n value={hydrated.datePeriod}\r\n onValueChange={(value) => {\r\n onSettingsChange?.({ ...hydrated, datePeriod: value as DatePeriodOption })\r\n }}\r\n >\r\n <SelectTrigger id=\"sales-new-orders-date-period\" size=\"sm\">\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"last24h\">{translate('sales.widgets.newOrders.settings.last24h', 'Last 24 hours')}</SelectItem>\r\n <SelectItem value=\"last7d\">{translate('sales.widgets.newOrders.settings.last7d', 'Last 7 days')}</SelectItem>\r\n <SelectItem value=\"last30d\">{translate('sales.widgets.newOrders.settings.last30d', 'Last 30 days')}</SelectItem>\r\n <SelectItem value=\"custom\">{translate('sales.widgets.newOrders.settings.custom', 'Custom range')}</SelectItem>\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {hydrated.datePeriod === 'custom' ? (\r\n <div className=\"grid gap-3\">\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-orders-custom-from\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newOrders.settings.customFrom', 'From')}\r\n </label>\r\n <input\r\n id=\"sales-new-orders-custom-from\"\r\n type=\"date\"\r\n value={toDateInputValue(hydrated.customFrom)}\r\n onChange={(event) => {\r\n onSettingsChange?.({ ...hydrated, customFrom: event.target.value })\r\n }}\r\n onFocus={openNativeDatePicker}\r\n onClick={openNativeDatePicker}\r\n className=\"w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n />\r\n </div>\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-orders-custom-to\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newOrders.settings.customTo', 'To')}\r\n </label>\r\n <input\r\n id=\"sales-new-orders-custom-to\"\r\n type=\"date\"\r\n value={toDateInputValue(hydrated.customTo)}\r\n onChange={(event) => {\r\n onSettingsChange?.({ ...hydrated, customTo: event.target.value })\r\n }}\r\n onFocus={openNativeDatePicker}\r\n onClick={openNativeDatePicker}\r\n className=\"w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n />\r\n </div>\r\n </div>\r\n ) : null}\r\n </div>\r\n )\r\n }\r\n\r\n if (error) {\r\n return <p className=\"text-sm text-destructive\">{error}</p>\r\n }\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex h-32 items-center justify-center\">\r\n <Spinner className=\"h-6 w-6 text-muted-foreground\" />\r\n </div>\r\n )\r\n }\r\n\r\n if (!items.length) {\r\n return <p className=\"text-sm text-muted-foreground\">{translate('sales.widgets.newOrders.empty', 'No orders found')}</p>\r\n }\r\n\r\n return (\r\n <ul className=\"space-y-3\">\r\n {items.map((item) => {\r\n const detailHref = resolveDetailHref(item)\r\n const amountLabel = formatAmount(item.grossAmount, item.currency, locale)\r\n const createdLabel = formatRelativeTime(item.createdAt) ?? ''\r\n return (\r\n <li key={item.id} className=\"rounded-md border p-3\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"space-y-1\">\r\n <div className=\"flex items-center gap-2\">\r\n {detailHref ? (\r\n <Link href={detailHref} className=\"text-sm font-semibold text-foreground hover:underline\">\r\n {item.orderNumber}\r\n </Link>\r\n ) : (\r\n <span className=\"text-sm font-semibold text-foreground\">{item.orderNumber}</span>\r\n )}\r\n {item.status ? (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {item.status}\r\n </Badge>\r\n ) : null}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {item.customerName ?? translate('sales.widgets.newOrders.noCustomer', 'No customer')}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground\">{createdLabel}</p>\r\n </div>\r\n <div className=\"text-right\">\r\n <p className=\"text-sm font-semibold\">{amountLabel}</p>\r\n </div>\r\n </div>\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n )\r\n}\r\n\r\nexport default SalesNewOrdersWidget\r\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -3,6 +3,14 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import Link from "next/link";
5
5
  import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
6
+ import { Input } from "@open-mercato/ui/primitives/input";
7
+ import {
8
+ Select,
9
+ SelectContent,
10
+ SelectItem,
11
+ SelectTrigger,
12
+ SelectValue
13
+ } from "@open-mercato/ui/primitives/select";
6
14
  import { Spinner } from "@open-mercato/ui/primitives/spinner";
7
15
  import { Badge } from "@open-mercato/ui/primitives/badge";
8
16
  import { formatRelativeTime } from "@open-mercato/shared/lib/time";
@@ -95,13 +103,13 @@ const SalesNewQuotesWidget = ({
95
103
  /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
96
104
  /* @__PURE__ */ jsx("label", { htmlFor: "sales-new-quotes-page-size", className: "text-xs font-semibold uppercase text-muted-foreground", children: translate("sales.widgets.newQuotes.settings.pageSize", "Number of Quotes") }),
97
105
  /* @__PURE__ */ jsx(
98
- "input",
106
+ Input,
99
107
  {
100
108
  id: "sales-new-quotes-page-size",
101
109
  type: "number",
102
110
  min: 1,
103
111
  max: 20,
104
- className: "w-24 rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
112
+ className: "w-24",
105
113
  value: hydrated.pageSize,
106
114
  onChange: (event) => {
107
115
  const next = Number(event.target.value);
@@ -115,19 +123,20 @@ const SalesNewQuotesWidget = ({
115
123
  /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
116
124
  /* @__PURE__ */ jsx("label", { htmlFor: "sales-new-quotes-date-period", className: "text-xs font-semibold uppercase text-muted-foreground", children: translate("sales.widgets.newQuotes.settings.datePeriod", "Date Period") }),
117
125
  /* @__PURE__ */ jsxs(
118
- "select",
126
+ Select,
119
127
  {
120
- id: "sales-new-quotes-date-period",
121
128
  value: hydrated.datePeriod,
122
- onChange: (event) => {
123
- onSettingsChange?.({ ...hydrated, datePeriod: event.target.value });
129
+ onValueChange: (value) => {
130
+ onSettingsChange?.({ ...hydrated, datePeriod: value });
124
131
  },
125
- className: "w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring",
126
132
  children: [
127
- /* @__PURE__ */ jsx("option", { value: "last24h", children: translate("sales.widgets.newQuotes.settings.last24h", "Last 24 hours") }),
128
- /* @__PURE__ */ jsx("option", { value: "last7d", children: translate("sales.widgets.newQuotes.settings.last7d", "Last 7 days") }),
129
- /* @__PURE__ */ jsx("option", { value: "last30d", children: translate("sales.widgets.newQuotes.settings.last30d", "Last 30 days") }),
130
- /* @__PURE__ */ jsx("option", { value: "custom", children: translate("sales.widgets.newQuotes.settings.custom", "Custom range") })
133
+ /* @__PURE__ */ jsx(SelectTrigger, { id: "sales-new-quotes-date-period", size: "sm", children: /* @__PURE__ */ jsx(SelectValue, {}) }),
134
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
135
+ /* @__PURE__ */ jsx(SelectItem, { value: "last24h", children: translate("sales.widgets.newQuotes.settings.last24h", "Last 24 hours") }),
136
+ /* @__PURE__ */ jsx(SelectItem, { value: "last7d", children: translate("sales.widgets.newQuotes.settings.last7d", "Last 7 days") }),
137
+ /* @__PURE__ */ jsx(SelectItem, { value: "last30d", children: translate("sales.widgets.newQuotes.settings.last30d", "Last 30 days") }),
138
+ /* @__PURE__ */ jsx(SelectItem, { value: "custom", children: translate("sales.widgets.newQuotes.settings.custom", "Custom range") })
139
+ ] })
131
140
  ]
132
141
  }
133
142
  )
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/sales/widgets/dashboard/new-quotes/widget.client.tsx"],
4
- "sourcesContent": ["\"use client\"\r\n\r\nimport * as React from 'react'\r\nimport Link from 'next/link'\r\nimport type { DashboardWidgetComponentProps } from '@open-mercato/shared/modules/dashboard/widgets'\r\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\r\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\r\nimport { Badge } from '@open-mercato/ui/primitives/badge'\r\nimport { formatRelativeTime } from '@open-mercato/shared/lib/time'\r\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\r\nimport { DEFAULT_SETTINGS, hydrateSalesNewQuotesSettings, type DatePeriodOption, type SalesNewQuotesSettings } from './config'\r\nimport { readString, toDateInputValue, openNativeDatePicker, formatAmount } from '../shared'\r\n\r\ntype NewQuoteItem = {\r\n id: string\r\n quoteNumber: string\r\n status: string | null\r\n customerName: string | null\r\n customerEntityId: string | null\r\n netAmount: string\r\n grossAmount: string\r\n currency: string | null\r\n createdAt: string\r\n validFrom: string | null\r\n validUntil: string | null\r\n convertedOrderId: string | null\r\n}\r\n\r\ntype NewQuotesApiPayload = {\r\n items?: unknown[]\r\n error?: string\r\n}\r\n\r\nfunction parseNewQuoteItems(payload: NewQuotesApiPayload | null): NewQuoteItem[] {\r\n const rawItems = Array.isArray(payload?.items) ? payload?.items : []\r\n return rawItems\r\n .map((item) => {\r\n if (!item || typeof item !== 'object') return null\r\n const data = item as Record<string, unknown>\r\n const id = readString(data.id)\r\n const quoteNumber = readString(data.quoteNumber)\r\n const createdAt = readString(data.createdAt)\r\n if (!id || !quoteNumber || !createdAt) return null\r\n return {\r\n id,\r\n quoteNumber,\r\n status: readString(data.status),\r\n customerName: readString(data.customerName),\r\n customerEntityId: readString(data.customerEntityId),\r\n netAmount: readString(data.netAmount) ?? '0',\r\n grossAmount: readString(data.grossAmount) ?? '0',\r\n currency: readString(data.currency),\r\n createdAt,\r\n validFrom: readString(data.validFrom),\r\n validUntil: readString(data.validUntil),\r\n convertedOrderId: readString(data.convertedOrderId),\r\n }\r\n })\r\n .filter((item): item is NewQuoteItem => !!item)\r\n}\r\n\r\nasync function loadNewQuotes(settings: SalesNewQuotesSettings): Promise<NewQuoteItem[]> {\r\n const params = new URLSearchParams({\r\n limit: String(settings.pageSize),\r\n datePeriod: settings.datePeriod,\r\n })\r\n if (settings.datePeriod === 'custom') {\r\n if (settings.customFrom) params.set('customFrom', settings.customFrom)\r\n if (settings.customTo) params.set('customTo', settings.customTo)\r\n }\r\n\r\n const call = await apiCall<NewQuotesApiPayload>(`/api/sales/dashboard/widgets/new-quotes?${params.toString()}`)\r\n if (!call.ok) {\r\n const message =\r\n typeof (call.result as Record<string, unknown> | null)?.error === 'string'\r\n ? ((call.result as Record<string, unknown>).error as string)\r\n : `Request failed with status ${call.status}`\r\n throw new Error(message)\r\n }\r\n return parseNewQuoteItems(call.result ?? null)\r\n}\r\n\r\nfunction resolveDetailHref(item: NewQuoteItem): string | null {\r\n return item.id ? `/backend/sales/quotes/${encodeURIComponent(item.id)}` : null\r\n}\r\n\r\n\r\nconst SalesNewQuotesWidget: React.FC<DashboardWidgetComponentProps<SalesNewQuotesSettings>> = ({\r\n mode,\r\n settings = DEFAULT_SETTINGS,\r\n onSettingsChange,\r\n refreshToken,\r\n onRefreshStateChange,\r\n}) => {\r\n const translate = useT()\r\n const hydrated = React.useMemo(() => hydrateSalesNewQuotesSettings(settings), [settings])\r\n const [items, setItems] = React.useState<NewQuoteItem[]>([])\r\n const [loading, setLoading] = React.useState(true)\r\n const [error, setError] = React.useState<string | null>(null)\r\n const [locale, setLocale] = React.useState<string | undefined>(undefined)\r\n\r\n React.useEffect(() => {\r\n if (typeof navigator !== 'undefined') {\r\n setLocale(navigator.language)\r\n }\r\n }, [])\r\n\r\n const refresh = React.useCallback(async () => {\r\n onRefreshStateChange?.(true)\r\n setLoading(true)\r\n setError(null)\r\n try {\r\n const data = await loadNewQuotes(hydrated)\r\n setItems(data)\r\n } catch (err) {\r\n console.error('Failed to load new quotes widget data', err)\r\n setError(translate('sales.widgets.newQuotes.error', 'Failed to load quotes'))\r\n } finally {\r\n setLoading(false)\r\n onRefreshStateChange?.(false)\r\n }\r\n }, [hydrated, onRefreshStateChange, translate])\r\n\r\n React.useEffect(() => {\r\n refresh().catch(() => {})\r\n }, [refresh, refreshToken])\r\n\r\n if (mode === 'settings') {\r\n return (\r\n <div className=\"space-y-4 text-sm\">\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-quotes-page-size\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newQuotes.settings.pageSize', 'Number of Quotes')}\r\n </label>\r\n <input\r\n id=\"sales-new-quotes-page-size\"\r\n type=\"number\"\r\n min={1}\r\n max={20}\r\n className=\"w-24 rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n value={hydrated.pageSize}\r\n onChange={(event) => {\r\n const next = Number(event.target.value)\r\n if (!Number.isFinite(next)) return\r\n const clamped = Math.min(20, Math.max(1, Math.floor(next)))\r\n onSettingsChange?.({ ...hydrated, pageSize: clamped })\r\n }}\r\n />\r\n </div>\r\n\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-quotes-date-period\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newQuotes.settings.datePeriod', 'Date Period')}\r\n </label>\r\n <select\r\n id=\"sales-new-quotes-date-period\"\r\n value={hydrated.datePeriod}\r\n onChange={(event) => {\r\n onSettingsChange?.({ ...hydrated, datePeriod: event.target.value as DatePeriodOption })\r\n }}\r\n className=\"w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n >\r\n <option value=\"last24h\">{translate('sales.widgets.newQuotes.settings.last24h', 'Last 24 hours')}</option>\r\n <option value=\"last7d\">{translate('sales.widgets.newQuotes.settings.last7d', 'Last 7 days')}</option>\r\n <option value=\"last30d\">{translate('sales.widgets.newQuotes.settings.last30d', 'Last 30 days')}</option>\r\n <option value=\"custom\">{translate('sales.widgets.newQuotes.settings.custom', 'Custom range')}</option>\r\n </select>\r\n </div>\r\n\r\n {hydrated.datePeriod === 'custom' ? (\r\n <div className=\"grid gap-3\">\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-quotes-custom-from\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newQuotes.settings.customFrom', 'From')}\r\n </label>\r\n <input\r\n id=\"sales-new-quotes-custom-from\"\r\n type=\"date\"\r\n value={toDateInputValue(hydrated.customFrom)}\r\n onChange={(event) => {\r\n onSettingsChange?.({ ...hydrated, customFrom: event.target.value })\r\n }}\r\n onFocus={openNativeDatePicker}\r\n onClick={openNativeDatePicker}\r\n className=\"w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n />\r\n </div>\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-quotes-custom-to\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newQuotes.settings.customTo', 'To')}\r\n </label>\r\n <input\r\n id=\"sales-new-quotes-custom-to\"\r\n type=\"date\"\r\n value={toDateInputValue(hydrated.customTo)}\r\n onChange={(event) => {\r\n onSettingsChange?.({ ...hydrated, customTo: event.target.value })\r\n }}\r\n onFocus={openNativeDatePicker}\r\n onClick={openNativeDatePicker}\r\n className=\"w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n />\r\n </div>\r\n </div>\r\n ) : null}\r\n </div>\r\n )\r\n }\r\n\r\n if (error) {\r\n return <p className=\"text-sm text-destructive\">{error}</p>\r\n }\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex h-32 items-center justify-center\">\r\n <Spinner className=\"h-6 w-6 text-muted-foreground\" />\r\n </div>\r\n )\r\n }\r\n\r\n if (!items.length) {\r\n return <p className=\"text-sm text-muted-foreground\">{translate('sales.widgets.newQuotes.empty', 'No quotes found')}</p>\r\n }\r\n\r\n return (\r\n <ul className=\"space-y-3\">\r\n {items.map((item) => {\r\n const detailHref = resolveDetailHref(item)\r\n const amountLabel = formatAmount(item.grossAmount, item.currency, locale)\r\n const createdLabel = formatRelativeTime(item.createdAt) ?? ''\r\n return (\r\n <li key={item.id} className=\"rounded-md border p-3\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"space-y-1\">\r\n <div className=\"flex items-center gap-2\">\r\n {detailHref ? (\r\n <Link href={detailHref} className=\"text-sm font-semibold text-foreground hover:underline\">\r\n {item.quoteNumber}\r\n </Link>\r\n ) : (\r\n <span className=\"text-sm font-semibold text-foreground\">{item.quoteNumber}</span>\r\n )}\r\n {item.status ? (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {item.status}\r\n </Badge>\r\n ) : null}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {item.customerName ?? translate('sales.widgets.newQuotes.noCustomer', 'No customer')}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground\">{createdLabel}</p>\r\n </div>\r\n <div className=\"text-right\">\r\n <p className=\"text-sm font-semibold\">{amountLabel}</p>\r\n </div>\r\n </div>\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n )\r\n}\r\n\r\nexport default SalesNewQuotesWidget\r\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\r\n\r\nimport * as React from 'react'\r\nimport Link from 'next/link'\r\nimport type { DashboardWidgetComponentProps } from '@open-mercato/shared/modules/dashboard/widgets'\r\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\r\nimport { Input } from '@open-mercato/ui/primitives/input'\r\nimport {\r\n Select,\r\n SelectContent,\r\n SelectItem,\r\n SelectTrigger,\r\n SelectValue,\r\n} from '@open-mercato/ui/primitives/select'\r\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\r\nimport { Badge } from '@open-mercato/ui/primitives/badge'\r\nimport { formatRelativeTime } from '@open-mercato/shared/lib/time'\r\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\r\nimport { DEFAULT_SETTINGS, hydrateSalesNewQuotesSettings, type DatePeriodOption, type SalesNewQuotesSettings } from './config'\r\nimport { readString, toDateInputValue, openNativeDatePicker, formatAmount } from '../shared'\r\n\r\ntype NewQuoteItem = {\r\n id: string\r\n quoteNumber: string\r\n status: string | null\r\n customerName: string | null\r\n customerEntityId: string | null\r\n netAmount: string\r\n grossAmount: string\r\n currency: string | null\r\n createdAt: string\r\n validFrom: string | null\r\n validUntil: string | null\r\n convertedOrderId: string | null\r\n}\r\n\r\ntype NewQuotesApiPayload = {\r\n items?: unknown[]\r\n error?: string\r\n}\r\n\r\nfunction parseNewQuoteItems(payload: NewQuotesApiPayload | null): NewQuoteItem[] {\r\n const rawItems = Array.isArray(payload?.items) ? payload?.items : []\r\n return rawItems\r\n .map((item) => {\r\n if (!item || typeof item !== 'object') return null\r\n const data = item as Record<string, unknown>\r\n const id = readString(data.id)\r\n const quoteNumber = readString(data.quoteNumber)\r\n const createdAt = readString(data.createdAt)\r\n if (!id || !quoteNumber || !createdAt) return null\r\n return {\r\n id,\r\n quoteNumber,\r\n status: readString(data.status),\r\n customerName: readString(data.customerName),\r\n customerEntityId: readString(data.customerEntityId),\r\n netAmount: readString(data.netAmount) ?? '0',\r\n grossAmount: readString(data.grossAmount) ?? '0',\r\n currency: readString(data.currency),\r\n createdAt,\r\n validFrom: readString(data.validFrom),\r\n validUntil: readString(data.validUntil),\r\n convertedOrderId: readString(data.convertedOrderId),\r\n }\r\n })\r\n .filter((item): item is NewQuoteItem => !!item)\r\n}\r\n\r\nasync function loadNewQuotes(settings: SalesNewQuotesSettings): Promise<NewQuoteItem[]> {\r\n const params = new URLSearchParams({\r\n limit: String(settings.pageSize),\r\n datePeriod: settings.datePeriod,\r\n })\r\n if (settings.datePeriod === 'custom') {\r\n if (settings.customFrom) params.set('customFrom', settings.customFrom)\r\n if (settings.customTo) params.set('customTo', settings.customTo)\r\n }\r\n\r\n const call = await apiCall<NewQuotesApiPayload>(`/api/sales/dashboard/widgets/new-quotes?${params.toString()}`)\r\n if (!call.ok) {\r\n const message =\r\n typeof (call.result as Record<string, unknown> | null)?.error === 'string'\r\n ? ((call.result as Record<string, unknown>).error as string)\r\n : `Request failed with status ${call.status}`\r\n throw new Error(message)\r\n }\r\n return parseNewQuoteItems(call.result ?? null)\r\n}\r\n\r\nfunction resolveDetailHref(item: NewQuoteItem): string | null {\r\n return item.id ? `/backend/sales/quotes/${encodeURIComponent(item.id)}` : null\r\n}\r\n\r\n\r\nconst SalesNewQuotesWidget: React.FC<DashboardWidgetComponentProps<SalesNewQuotesSettings>> = ({\r\n mode,\r\n settings = DEFAULT_SETTINGS,\r\n onSettingsChange,\r\n refreshToken,\r\n onRefreshStateChange,\r\n}) => {\r\n const translate = useT()\r\n const hydrated = React.useMemo(() => hydrateSalesNewQuotesSettings(settings), [settings])\r\n const [items, setItems] = React.useState<NewQuoteItem[]>([])\r\n const [loading, setLoading] = React.useState(true)\r\n const [error, setError] = React.useState<string | null>(null)\r\n const [locale, setLocale] = React.useState<string | undefined>(undefined)\r\n\r\n React.useEffect(() => {\r\n if (typeof navigator !== 'undefined') {\r\n setLocale(navigator.language)\r\n }\r\n }, [])\r\n\r\n const refresh = React.useCallback(async () => {\r\n onRefreshStateChange?.(true)\r\n setLoading(true)\r\n setError(null)\r\n try {\r\n const data = await loadNewQuotes(hydrated)\r\n setItems(data)\r\n } catch (err) {\r\n console.error('Failed to load new quotes widget data', err)\r\n setError(translate('sales.widgets.newQuotes.error', 'Failed to load quotes'))\r\n } finally {\r\n setLoading(false)\r\n onRefreshStateChange?.(false)\r\n }\r\n }, [hydrated, onRefreshStateChange, translate])\r\n\r\n React.useEffect(() => {\r\n refresh().catch(() => {})\r\n }, [refresh, refreshToken])\r\n\r\n if (mode === 'settings') {\r\n return (\r\n <div className=\"space-y-4 text-sm\">\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-quotes-page-size\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newQuotes.settings.pageSize', 'Number of Quotes')}\r\n </label>\r\n <Input\r\n id=\"sales-new-quotes-page-size\"\r\n type=\"number\"\r\n min={1}\r\n max={20}\r\n className=\"w-24\"\r\n value={hydrated.pageSize}\r\n onChange={(event) => {\r\n const next = Number(event.target.value)\r\n if (!Number.isFinite(next)) return\r\n const clamped = Math.min(20, Math.max(1, Math.floor(next)))\r\n onSettingsChange?.({ ...hydrated, pageSize: clamped })\r\n }}\r\n />\r\n </div>\r\n\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-quotes-date-period\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newQuotes.settings.datePeriod', 'Date Period')}\r\n </label>\r\n <Select\r\n value={hydrated.datePeriod}\r\n onValueChange={(value) => {\r\n onSettingsChange?.({ ...hydrated, datePeriod: value as DatePeriodOption })\r\n }}\r\n >\r\n <SelectTrigger id=\"sales-new-quotes-date-period\" size=\"sm\">\r\n <SelectValue />\r\n </SelectTrigger>\r\n <SelectContent>\r\n <SelectItem value=\"last24h\">{translate('sales.widgets.newQuotes.settings.last24h', 'Last 24 hours')}</SelectItem>\r\n <SelectItem value=\"last7d\">{translate('sales.widgets.newQuotes.settings.last7d', 'Last 7 days')}</SelectItem>\r\n <SelectItem value=\"last30d\">{translate('sales.widgets.newQuotes.settings.last30d', 'Last 30 days')}</SelectItem>\r\n <SelectItem value=\"custom\">{translate('sales.widgets.newQuotes.settings.custom', 'Custom range')}</SelectItem>\r\n </SelectContent>\r\n </Select>\r\n </div>\r\n\r\n {hydrated.datePeriod === 'custom' ? (\r\n <div className=\"grid gap-3\">\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-quotes-custom-from\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newQuotes.settings.customFrom', 'From')}\r\n </label>\r\n <input\r\n id=\"sales-new-quotes-custom-from\"\r\n type=\"date\"\r\n value={toDateInputValue(hydrated.customFrom)}\r\n onChange={(event) => {\r\n onSettingsChange?.({ ...hydrated, customFrom: event.target.value })\r\n }}\r\n onFocus={openNativeDatePicker}\r\n onClick={openNativeDatePicker}\r\n className=\"w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n />\r\n </div>\r\n <div className=\"space-y-1.5\">\r\n <label htmlFor=\"sales-new-quotes-custom-to\" className=\"text-xs font-semibold uppercase text-muted-foreground\">\r\n {translate('sales.widgets.newQuotes.settings.customTo', 'To')}\r\n </label>\r\n <input\r\n id=\"sales-new-quotes-custom-to\"\r\n type=\"date\"\r\n value={toDateInputValue(hydrated.customTo)}\r\n onChange={(event) => {\r\n onSettingsChange?.({ ...hydrated, customTo: event.target.value })\r\n }}\r\n onFocus={openNativeDatePicker}\r\n onClick={openNativeDatePicker}\r\n className=\"w-full rounded-md border border-input bg-background px-2 py-1 text-sm text-foreground focus-visible:border-ring focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring\"\r\n />\r\n </div>\r\n </div>\r\n ) : null}\r\n </div>\r\n )\r\n }\r\n\r\n if (error) {\r\n return <p className=\"text-sm text-destructive\">{error}</p>\r\n }\r\n\r\n if (loading) {\r\n return (\r\n <div className=\"flex h-32 items-center justify-center\">\r\n <Spinner className=\"h-6 w-6 text-muted-foreground\" />\r\n </div>\r\n )\r\n }\r\n\r\n if (!items.length) {\r\n return <p className=\"text-sm text-muted-foreground\">{translate('sales.widgets.newQuotes.empty', 'No quotes found')}</p>\r\n }\r\n\r\n return (\r\n <ul className=\"space-y-3\">\r\n {items.map((item) => {\r\n const detailHref = resolveDetailHref(item)\r\n const amountLabel = formatAmount(item.grossAmount, item.currency, locale)\r\n const createdLabel = formatRelativeTime(item.createdAt) ?? ''\r\n return (\r\n <li key={item.id} className=\"rounded-md border p-3\">\r\n <div className=\"flex items-start justify-between gap-3\">\r\n <div className=\"space-y-1\">\r\n <div className=\"flex items-center gap-2\">\r\n {detailHref ? (\r\n <Link href={detailHref} className=\"text-sm font-semibold text-foreground hover:underline\">\r\n {item.quoteNumber}\r\n </Link>\r\n ) : (\r\n <span className=\"text-sm font-semibold text-foreground\">{item.quoteNumber}</span>\r\n )}\r\n {item.status ? (\r\n <Badge variant=\"outline\" className=\"text-xs\">\r\n {item.status}\r\n </Badge>\r\n ) : null}\r\n </div>\r\n <p className=\"text-xs text-muted-foreground\">\r\n {item.customerName ?? translate('sales.widgets.newQuotes.noCustomer', 'No customer')}\r\n </p>\r\n <p className=\"text-xs text-muted-foreground\">{createdLabel}</p>\r\n </div>\r\n <div className=\"text-right\">\r\n <p className=\"text-sm font-semibold\">{amountLabel}</p>\r\n </div>\r\n </div>\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n )\r\n}\r\n\r\nexport default SalesNewQuotesWidget\r\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,6 +2,14 @@
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
3
  import * as React from "react";
4
4
  import { Button } from "@open-mercato/ui/primitives/button";
5
+ import { Input } from "@open-mercato/ui/primitives/input";
6
+ import {
7
+ Select,
8
+ SelectContent,
9
+ SelectItem,
10
+ SelectTrigger,
11
+ SelectValue
12
+ } from "@open-mercato/ui/primitives/select";
5
13
  import { Spinner } from "@open-mercato/ui/primitives/spinner";
6
14
  import { Card, CardContent, CardHeader, CardTitle } from "@open-mercato/ui/primitives/card";
7
15
  import { useT } from "@open-mercato/shared/lib/i18n/context";
@@ -62,14 +70,15 @@ const ConfigureStep = (props) => {
62
70
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
63
71
  /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: t("shipping_carriers.create.field.phone", "Phone") }),
64
72
  /* @__PURE__ */ jsx(
65
- "input",
73
+ Input,
66
74
  {
67
- className: `w-full rounded border bg-background px-2 py-1.5 text-sm ${senderContactErrors.phone ? "border-destructive" : ""}`,
68
75
  type: "tel",
76
+ size: "sm",
69
77
  value: senderContact.phone,
70
78
  onChange: (e) => onSenderContactChange({ ...senderContact, phone: e.target.value }),
71
79
  disabled: isFetchingRates,
72
- placeholder: "e.g. 500000000"
80
+ placeholder: "e.g. 500000000",
81
+ "aria-invalid": senderContactErrors.phone ? true : void 0
73
82
  }
74
83
  ),
75
84
  senderContactErrors.phone ? /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: senderContactErrors.phone }) : null
@@ -77,14 +86,15 @@ const ConfigureStep = (props) => {
77
86
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
78
87
  /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: t("shipping_carriers.create.field.email", "Email") }),
79
88
  /* @__PURE__ */ jsx(
80
- "input",
89
+ Input,
81
90
  {
82
- className: `w-full rounded border bg-background px-2 py-1.5 text-sm ${senderContactErrors.email ? "border-destructive" : ""}`,
83
91
  type: "email",
92
+ size: "sm",
84
93
  value: senderContact.email,
85
94
  onChange: (e) => onSenderContactChange({ ...senderContact, email: e.target.value }),
86
95
  disabled: isFetchingRates,
87
- placeholder: "e.g. sender@example.com"
96
+ placeholder: "e.g. sender@example.com",
97
+ "aria-invalid": senderContactErrors.email ? true : void 0
88
98
  }
89
99
  ),
90
100
  senderContactErrors.email ? /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: senderContactErrors.email }) : null
@@ -97,14 +107,15 @@ const ConfigureStep = (props) => {
97
107
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
98
108
  /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: t("shipping_carriers.create.field.phone", "Phone") }),
99
109
  /* @__PURE__ */ jsx(
100
- "input",
110
+ Input,
101
111
  {
102
- className: `w-full rounded border bg-background px-2 py-1.5 text-sm ${receiverContactErrors.phone ? "border-destructive" : ""}`,
103
112
  type: "tel",
113
+ size: "sm",
104
114
  value: receiverContact.phone,
105
115
  onChange: (e) => onReceiverContactChange({ ...receiverContact, phone: e.target.value }),
106
116
  disabled: isFetchingRates,
107
- placeholder: "e.g. 500000000"
117
+ placeholder: "e.g. 500000000",
118
+ "aria-invalid": receiverContactErrors.phone ? true : void 0
108
119
  }
109
120
  ),
110
121
  receiverContactErrors.phone ? /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: receiverContactErrors.phone }) : null
@@ -112,14 +123,15 @@ const ConfigureStep = (props) => {
112
123
  /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
113
124
  /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: t("shipping_carriers.create.field.email", "Email") }),
114
125
  /* @__PURE__ */ jsx(
115
- "input",
126
+ Input,
116
127
  {
117
- className: `w-full rounded border bg-background px-2 py-1.5 text-sm ${receiverContactErrors.email ? "border-destructive" : ""}`,
118
128
  type: "email",
129
+ size: "sm",
119
130
  value: receiverContact.email,
120
131
  onChange: (e) => onReceiverContactChange({ ...receiverContact, email: e.target.value }),
121
132
  disabled: isFetchingRates,
122
- placeholder: "e.g. receiver@example.com"
133
+ placeholder: "e.g. receiver@example.com",
134
+ "aria-invalid": receiverContactErrors.email ? true : void 0
123
135
  }
124
136
  ),
125
137
  receiverContactErrors.email ? /* @__PURE__ */ jsx("p", { className: "text-xs text-destructive", children: receiverContactErrors.email }) : null
@@ -132,17 +144,18 @@ const ConfigureStep = (props) => {
132
144
  /* @__PURE__ */ jsx(CardContent, { children: /* @__PURE__ */ jsxs("div", { className: "space-y-1", children: [
133
145
  /* @__PURE__ */ jsx("label", { className: "text-xs font-medium text-muted-foreground", children: t("shipping_carriers.create.field.c2cSendingMethod", "Sending method (applies to courier_c2c service only)") }),
134
146
  /* @__PURE__ */ jsxs(
135
- "select",
147
+ Select,
136
148
  {
137
- className: "w-full rounded border bg-background px-2 py-1.5 text-sm",
138
- value: c2cSendingMethod,
139
- onChange: (e) => onC2cSendingMethodChange(e.target.value),
149
+ value: c2cSendingMethod || void 0,
150
+ onValueChange: (value) => onC2cSendingMethodChange(value ?? ""),
140
151
  disabled: isFetchingRates,
141
152
  children: [
142
- /* @__PURE__ */ jsx("option", { value: "", children: t("shipping_carriers.create.c2cSendingMethod.default", "Dispatch order (default)") }),
143
- /* @__PURE__ */ jsx("option", { value: "parcel_locker", children: t("shipping_carriers.create.c2cSendingMethod.parcel_locker", "Parcel locker") }),
144
- /* @__PURE__ */ jsx("option", { value: "pop", children: t("shipping_carriers.create.c2cSendingMethod.pop", "POP (parcel pickup point)") }),
145
- /* @__PURE__ */ jsx("option", { value: "any_point", children: t("shipping_carriers.create.c2cSendingMethod.any_point", "Any point") })
153
+ /* @__PURE__ */ jsx(SelectTrigger, { size: "sm", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: t("shipping_carriers.create.c2cSendingMethod.default", "Dispatch order (default)") }) }),
154
+ /* @__PURE__ */ jsxs(SelectContent, { children: [
155
+ /* @__PURE__ */ jsx(SelectItem, { value: "parcel_locker", children: t("shipping_carriers.create.c2cSendingMethod.parcel_locker", "Parcel locker") }),
156
+ /* @__PURE__ */ jsx(SelectItem, { value: "pop", children: t("shipping_carriers.create.c2cSendingMethod.pop", "POP (parcel pickup point)") }),
157
+ /* @__PURE__ */ jsx(SelectItem, { value: "any_point", children: t("shipping_carriers.create.c2cSendingMethod.any_point", "Any point") })
158
+ ] })
146
159
  ]
147
160
  }
148
161
  )
@@ -169,9 +182,10 @@ const ConfigureStep = (props) => {
169
182
  ] }),
170
183
  /* @__PURE__ */ jsxs("div", { className: "flex gap-2", children: [
171
184
  /* @__PURE__ */ jsx(
172
- "input",
185
+ Input,
173
186
  {
174
- className: "flex-1 rounded border bg-background px-2 py-1.5 text-sm",
187
+ size: "sm",
188
+ className: "flex-1",
175
189
  value: searchInput,
176
190
  onChange: (e) => setSearchInput(e.target.value),
177
191
  onKeyDown: (e) => {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { Card, CardContent, CardHeader, CardTitle } from '@open-mercato/ui/primitives/card'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { AddressFields } from './AddressFields'\nimport { PackageEditor } from './PackageEditor'\nimport type { Address, PackageDimension, LabelFormat, ContactInfo, DropOffPoint } from '../types'\n\nexport type ConfigureStepProps = {\n origin: Address\n destination: Address\n packages: PackageDimension[]\n labelFormat: LabelFormat\n senderContact: ContactInfo\n receiverContact: ContactInfo\n targetPoint: string\n c2cSendingMethod: string\n isFetchingRates: boolean\n canProceed: boolean\n senderContactErrors: { email: string | null; phone: string | null }\n receiverContactErrors: { email: string | null; phone: string | null }\n dropOffPointQuery: string\n dropOffPoints: DropOffPoint[]\n isFetchingDropOffPoints: boolean\n dropOffPointsError: string | null\n onOriginChange: (address: Address) => void\n onDestinationChange: (address: Address) => void\n onPackagesChange: (packages: PackageDimension[]) => void\n onLabelFormatChange: (format: LabelFormat) => void\n onSenderContactChange: (contact: ContactInfo) => void\n onReceiverContactChange: (contact: ContactInfo) => void\n onTargetPointChange: (point: string) => void\n onC2cSendingMethodChange: (method: string) => void\n onSearchDropOffPoints: (query: string) => void\n onBack: () => void\n onNext: () => void\n}\n\nconst LABEL_FORMATS: LabelFormat[] = ['pdf', 'zpl', 'png']\n\nexport const ConfigureStep = (props: ConfigureStepProps) => {\n const {\n origin, destination, packages, labelFormat,\n senderContact, receiverContact, targetPoint, c2cSendingMethod,\n isFetchingRates, canProceed,\n senderContactErrors, receiverContactErrors,\n dropOffPointQuery, dropOffPoints, isFetchingDropOffPoints, dropOffPointsError,\n onOriginChange, onDestinationChange, onPackagesChange, onLabelFormatChange,\n onSenderContactChange, onReceiverContactChange, onTargetPointChange, onC2cSendingMethodChange,\n onSearchDropOffPoints,\n onBack, onNext,\n } = props\n const t = useT()\n const [searchInput, setSearchInput] = React.useState(dropOffPointQuery)\n\n return (\n <section className=\"space-y-6\">\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.origin', 'Origin address')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <AddressFields prefix=\"origin\" address={origin} onChange={onOriginChange} disabled={isFetchingRates} />\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.destination', 'Destination address')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <AddressFields prefix=\"dest\" address={destination} onChange={onDestinationChange} disabled={isFetchingRates} />\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.packages', 'Packages')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <PackageEditor packages={packages} onChange={onPackagesChange} disabled={isFetchingRates} />\n </CardContent>\n </Card>\n\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.senderContact', 'Sender contact')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('shipping_carriers.create.field.phone', 'Phone')}\n </label>\n <input\n className={`w-full rounded border bg-background px-2 py-1.5 text-sm ${senderContactErrors.phone ? 'border-destructive' : ''}`}\n type=\"tel\"\n value={senderContact.phone}\n onChange={(e) => onSenderContactChange({ ...senderContact, phone: e.target.value })}\n disabled={isFetchingRates}\n placeholder=\"e.g. 500000000\"\n />\n {senderContactErrors.phone ? (\n <p className=\"text-xs text-destructive\">{senderContactErrors.phone}</p>\n ) : null}\n </div>\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('shipping_carriers.create.field.email', 'Email')}\n </label>\n <input\n className={`w-full rounded border bg-background px-2 py-1.5 text-sm ${senderContactErrors.email ? 'border-destructive' : ''}`}\n type=\"email\"\n value={senderContact.email}\n onChange={(e) => onSenderContactChange({ ...senderContact, email: e.target.value })}\n disabled={isFetchingRates}\n placeholder=\"e.g. sender@example.com\"\n />\n {senderContactErrors.email ? (\n <p className=\"text-xs text-destructive\">{senderContactErrors.email}</p>\n ) : null}\n </div>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.receiverContact', 'Receiver contact')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('shipping_carriers.create.field.phone', 'Phone')}\n </label>\n <input\n className={`w-full rounded border bg-background px-2 py-1.5 text-sm ${receiverContactErrors.phone ? 'border-destructive' : ''}`}\n type=\"tel\"\n value={receiverContact.phone}\n onChange={(e) => onReceiverContactChange({ ...receiverContact, phone: e.target.value })}\n disabled={isFetchingRates}\n placeholder=\"e.g. 500000000\"\n />\n {receiverContactErrors.phone ? (\n <p className=\"text-xs text-destructive\">{receiverContactErrors.phone}</p>\n ) : null}\n </div>\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('shipping_carriers.create.field.email', 'Email')}\n </label>\n <input\n className={`w-full rounded border bg-background px-2 py-1.5 text-sm ${receiverContactErrors.email ? 'border-destructive' : ''}`}\n type=\"email\"\n value={receiverContact.email}\n onChange={(e) => onReceiverContactChange({ ...receiverContact, email: e.target.value })}\n disabled={isFetchingRates}\n placeholder=\"e.g. receiver@example.com\"\n />\n {receiverContactErrors.email ? (\n <p className=\"text-xs text-destructive\">{receiverContactErrors.email}</p>\n ) : null}\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.c2cSendingMethod', 'C2C sending method')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('shipping_carriers.create.field.c2cSendingMethod', 'Sending method (applies to courier_c2c service only)')}\n </label>\n <select\n className=\"w-full rounded border bg-background px-2 py-1.5 text-sm\"\n value={c2cSendingMethod}\n onChange={(e) => onC2cSendingMethodChange(e.target.value)}\n disabled={isFetchingRates}\n >\n <option value=\"\">{t('shipping_carriers.create.c2cSendingMethod.default', 'Dispatch order (default)')}</option>\n <option value=\"parcel_locker\">{t('shipping_carriers.create.c2cSendingMethod.parcel_locker', 'Parcel locker')}</option>\n <option value=\"pop\">{t('shipping_carriers.create.c2cSendingMethod.pop', 'POP (parcel pickup point)')}</option>\n <option value=\"any_point\">{t('shipping_carriers.create.c2cSendingMethod.any_point', 'Any point')}</option>\n </select>\n </div>\n </CardContent>\n </Card>\n\n {(c2cSendingMethod === 'parcel_locker' || c2cSendingMethod === 'pop') && (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.dropOffPoint', 'Drop-off / locker point')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {targetPoint && (\n <div className=\"rounded border border-primary bg-primary/5 px-3 py-2 text-sm\">\n <span className=\"font-medium text-xs text-muted-foreground mr-2\">\n {t('shipping_carriers.create.field.selectedPoint', 'Selected:')}\n </span>\n <span className=\"font-mono font-medium\">{targetPoint}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-2 h-auto py-0 text-xs\"\n onClick={() => onTargetPointChange('')}\n disabled={isFetchingRates}\n >\n {t('shipping_carriers.create.action.clearPoint', 'Clear')}\n </Button>\n </div>\n )}\n\n <div className=\"flex gap-2\">\n <input\n className=\"flex-1 rounded border bg-background px-2 py-1.5 text-sm\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n onSearchDropOffPoints(searchInput)\n }\n }}\n disabled={isFetchingRates}\n placeholder={t('shipping_carriers.create.field.dropOffSearch', 'Postal code (e.g. 30-624) or point name (e.g. KRA012)')}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onSearchDropOffPoints(searchInput)}\n disabled={isFetchingRates || isFetchingDropOffPoints || searchInput.trim().length === 0}\n >\n {isFetchingDropOffPoints ? (\n <Spinner className=\"h-4 w-4\" />\n ) : (\n t('shipping_carriers.create.action.searchPoints', 'Search')\n )}\n </Button>\n </div>\n\n {dropOffPointsError && (\n <p className=\"text-xs text-destructive\">{dropOffPointsError}</p>\n )}\n\n {dropOffPoints.length > 0 && (\n <ul className=\"max-h-60 overflow-y-auto divide-y rounded border text-sm\">\n {dropOffPoints.map((point) => (\n <li key={point.id}>\n <button\n type=\"button\"\n className={`w-full px-3 py-2 text-left hover:bg-accent ${targetPoint === point.id ? 'bg-primary/5 font-medium' : ''}`}\n onClick={() => onTargetPointChange(point.id)}\n disabled={isFetchingRates}\n >\n <span className=\"font-mono mr-2\">{point.name}</span>\n <span className=\"text-muted-foreground text-xs\">\n {[point.street, point.city, point.postalCode].filter(Boolean).join(', ')}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n\n {!isFetchingDropOffPoints && dropOffPoints.length === 0 && dropOffPointQuery && !dropOffPointsError && (\n <p className=\"text-xs text-muted-foreground\">\n {t('shipping_carriers.create.dropOffPoints.noResults', 'No drop-off points found for this search.')}\n </p>\n )}\n </CardContent>\n </Card>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.labelFormat', 'Label format')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex gap-3\">\n {LABEL_FORMATS.map((fmt) => (\n <Button\n key={fmt}\n type=\"button\"\n variant={labelFormat === fmt ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => onLabelFormatChange(fmt)}\n disabled={isFetchingRates}\n >\n {fmt.toUpperCase()}\n </Button>\n ))}\n </div>\n </CardContent>\n </Card>\n\n <div className=\"flex justify-between gap-3\">\n <Button type=\"button\" variant=\"outline\" onClick={onBack} disabled={isFetchingRates}>\n {t('shipping_carriers.create.back', 'Back')}\n </Button>\n <Button type=\"button\" onClick={onNext} disabled={!canProceed || isFetchingRates}>\n {isFetchingRates ? (\n <>\n <Spinner className=\"mr-2 h-4 w-4\" />\n {t('shipping_carriers.create.fetchingRates', 'Fetching rates...')}\n </>\n ) : (\n t('shipping_carriers.create.getQuotes', 'Get quotes')\n )}\n </Button>\n </div>\n </section>\n )\n}\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\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 { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { Card, CardContent, CardHeader, CardTitle } from '@open-mercato/ui/primitives/card'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { AddressFields } from './AddressFields'\nimport { PackageEditor } from './PackageEditor'\nimport type { Address, PackageDimension, LabelFormat, ContactInfo, DropOffPoint } from '../types'\n\nexport type ConfigureStepProps = {\n origin: Address\n destination: Address\n packages: PackageDimension[]\n labelFormat: LabelFormat\n senderContact: ContactInfo\n receiverContact: ContactInfo\n targetPoint: string\n c2cSendingMethod: string\n isFetchingRates: boolean\n canProceed: boolean\n senderContactErrors: { email: string | null; phone: string | null }\n receiverContactErrors: { email: string | null; phone: string | null }\n dropOffPointQuery: string\n dropOffPoints: DropOffPoint[]\n isFetchingDropOffPoints: boolean\n dropOffPointsError: string | null\n onOriginChange: (address: Address) => void\n onDestinationChange: (address: Address) => void\n onPackagesChange: (packages: PackageDimension[]) => void\n onLabelFormatChange: (format: LabelFormat) => void\n onSenderContactChange: (contact: ContactInfo) => void\n onReceiverContactChange: (contact: ContactInfo) => void\n onTargetPointChange: (point: string) => void\n onC2cSendingMethodChange: (method: string) => void\n onSearchDropOffPoints: (query: string) => void\n onBack: () => void\n onNext: () => void\n}\n\nconst LABEL_FORMATS: LabelFormat[] = ['pdf', 'zpl', 'png']\n\nexport const ConfigureStep = (props: ConfigureStepProps) => {\n const {\n origin, destination, packages, labelFormat,\n senderContact, receiverContact, targetPoint, c2cSendingMethod,\n isFetchingRates, canProceed,\n senderContactErrors, receiverContactErrors,\n dropOffPointQuery, dropOffPoints, isFetchingDropOffPoints, dropOffPointsError,\n onOriginChange, onDestinationChange, onPackagesChange, onLabelFormatChange,\n onSenderContactChange, onReceiverContactChange, onTargetPointChange, onC2cSendingMethodChange,\n onSearchDropOffPoints,\n onBack, onNext,\n } = props\n const t = useT()\n const [searchInput, setSearchInput] = React.useState(dropOffPointQuery)\n\n return (\n <section className=\"space-y-6\">\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.origin', 'Origin address')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <AddressFields prefix=\"origin\" address={origin} onChange={onOriginChange} disabled={isFetchingRates} />\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.destination', 'Destination address')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <AddressFields prefix=\"dest\" address={destination} onChange={onDestinationChange} disabled={isFetchingRates} />\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.packages', 'Packages')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <PackageEditor packages={packages} onChange={onPackagesChange} disabled={isFetchingRates} />\n </CardContent>\n </Card>\n\n <div className=\"grid gap-6 lg:grid-cols-2\">\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.senderContact', 'Sender contact')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('shipping_carriers.create.field.phone', 'Phone')}\n </label>\n <Input\n type=\"tel\"\n size=\"sm\"\n value={senderContact.phone}\n onChange={(e) => onSenderContactChange({ ...senderContact, phone: e.target.value })}\n disabled={isFetchingRates}\n placeholder=\"e.g. 500000000\"\n aria-invalid={senderContactErrors.phone ? true : undefined}\n />\n {senderContactErrors.phone ? (\n <p className=\"text-xs text-destructive\">{senderContactErrors.phone}</p>\n ) : null}\n </div>\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('shipping_carriers.create.field.email', 'Email')}\n </label>\n <Input\n type=\"email\"\n size=\"sm\"\n value={senderContact.email}\n onChange={(e) => onSenderContactChange({ ...senderContact, email: e.target.value })}\n disabled={isFetchingRates}\n placeholder=\"e.g. sender@example.com\"\n aria-invalid={senderContactErrors.email ? true : undefined}\n />\n {senderContactErrors.email ? (\n <p className=\"text-xs text-destructive\">{senderContactErrors.email}</p>\n ) : null}\n </div>\n </div>\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.receiverContact', 'Receiver contact')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"grid gap-4 sm:grid-cols-2\">\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('shipping_carriers.create.field.phone', 'Phone')}\n </label>\n <Input\n type=\"tel\"\n size=\"sm\"\n value={receiverContact.phone}\n onChange={(e) => onReceiverContactChange({ ...receiverContact, phone: e.target.value })}\n disabled={isFetchingRates}\n placeholder=\"e.g. 500000000\"\n aria-invalid={receiverContactErrors.phone ? true : undefined}\n />\n {receiverContactErrors.phone ? (\n <p className=\"text-xs text-destructive\">{receiverContactErrors.phone}</p>\n ) : null}\n </div>\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('shipping_carriers.create.field.email', 'Email')}\n </label>\n <Input\n type=\"email\"\n size=\"sm\"\n value={receiverContact.email}\n onChange={(e) => onReceiverContactChange({ ...receiverContact, email: e.target.value })}\n disabled={isFetchingRates}\n placeholder=\"e.g. receiver@example.com\"\n aria-invalid={receiverContactErrors.email ? true : undefined}\n />\n {receiverContactErrors.email ? (\n <p className=\"text-xs text-destructive\">{receiverContactErrors.email}</p>\n ) : null}\n </div>\n </div>\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.c2cSendingMethod', 'C2C sending method')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"space-y-1\">\n <label className=\"text-xs font-medium text-muted-foreground\">\n {t('shipping_carriers.create.field.c2cSendingMethod', 'Sending method (applies to courier_c2c service only)')}\n </label>\n <Select\n value={c2cSendingMethod || undefined}\n onValueChange={(value) => onC2cSendingMethodChange(value ?? '')}\n disabled={isFetchingRates}\n >\n <SelectTrigger size=\"sm\">\n <SelectValue placeholder={t('shipping_carriers.create.c2cSendingMethod.default', 'Dispatch order (default)')} />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"parcel_locker\">{t('shipping_carriers.create.c2cSendingMethod.parcel_locker', 'Parcel locker')}</SelectItem>\n <SelectItem value=\"pop\">{t('shipping_carriers.create.c2cSendingMethod.pop', 'POP (parcel pickup point)')}</SelectItem>\n <SelectItem value=\"any_point\">{t('shipping_carriers.create.c2cSendingMethod.any_point', 'Any point')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n </CardContent>\n </Card>\n\n {(c2cSendingMethod === 'parcel_locker' || c2cSendingMethod === 'pop') && (\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.dropOffPoint', 'Drop-off / locker point')}\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-4\">\n {targetPoint && (\n <div className=\"rounded border border-primary bg-primary/5 px-3 py-2 text-sm\">\n <span className=\"font-medium text-xs text-muted-foreground mr-2\">\n {t('shipping_carriers.create.field.selectedPoint', 'Selected:')}\n </span>\n <span className=\"font-mono font-medium\">{targetPoint}</span>\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"ml-2 h-auto py-0 text-xs\"\n onClick={() => onTargetPointChange('')}\n disabled={isFetchingRates}\n >\n {t('shipping_carriers.create.action.clearPoint', 'Clear')}\n </Button>\n </div>\n )}\n\n <div className=\"flex gap-2\">\n <Input\n size=\"sm\"\n className=\"flex-1\"\n value={searchInput}\n onChange={(e) => setSearchInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === 'Enter') {\n e.preventDefault()\n onSearchDropOffPoints(searchInput)\n }\n }}\n disabled={isFetchingRates}\n placeholder={t('shipping_carriers.create.field.dropOffSearch', 'Postal code (e.g. 30-624) or point name (e.g. KRA012)')}\n />\n <Button\n type=\"button\"\n variant=\"outline\"\n size=\"sm\"\n onClick={() => onSearchDropOffPoints(searchInput)}\n disabled={isFetchingRates || isFetchingDropOffPoints || searchInput.trim().length === 0}\n >\n {isFetchingDropOffPoints ? (\n <Spinner className=\"h-4 w-4\" />\n ) : (\n t('shipping_carriers.create.action.searchPoints', 'Search')\n )}\n </Button>\n </div>\n\n {dropOffPointsError && (\n <p className=\"text-xs text-destructive\">{dropOffPointsError}</p>\n )}\n\n {dropOffPoints.length > 0 && (\n <ul className=\"max-h-60 overflow-y-auto divide-y rounded border text-sm\">\n {dropOffPoints.map((point) => (\n <li key={point.id}>\n <button\n type=\"button\"\n className={`w-full px-3 py-2 text-left hover:bg-accent ${targetPoint === point.id ? 'bg-primary/5 font-medium' : ''}`}\n onClick={() => onTargetPointChange(point.id)}\n disabled={isFetchingRates}\n >\n <span className=\"font-mono mr-2\">{point.name}</span>\n <span className=\"text-muted-foreground text-xs\">\n {[point.street, point.city, point.postalCode].filter(Boolean).join(', ')}\n </span>\n </button>\n </li>\n ))}\n </ul>\n )}\n\n {!isFetchingDropOffPoints && dropOffPoints.length === 0 && dropOffPointQuery && !dropOffPointsError && (\n <p className=\"text-xs text-muted-foreground\">\n {t('shipping_carriers.create.dropOffPoints.noResults', 'No drop-off points found for this search.')}\n </p>\n )}\n </CardContent>\n </Card>\n )}\n\n <Card>\n <CardHeader>\n <CardTitle className=\"text-base\">\n {t('shipping_carriers.create.section.labelFormat', 'Label format')}\n </CardTitle>\n </CardHeader>\n <CardContent>\n <div className=\"flex gap-3\">\n {LABEL_FORMATS.map((fmt) => (\n <Button\n key={fmt}\n type=\"button\"\n variant={labelFormat === fmt ? 'default' : 'outline'}\n size=\"sm\"\n onClick={() => onLabelFormatChange(fmt)}\n disabled={isFetchingRates}\n >\n {fmt.toUpperCase()}\n </Button>\n ))}\n </div>\n </CardContent>\n </Card>\n\n <div className=\"flex justify-between gap-3\">\n <Button type=\"button\" variant=\"outline\" onClick={onBack} disabled={isFetchingRates}>\n {t('shipping_carriers.create.back', 'Back')}\n </Button>\n <Button type=\"button\" onClick={onNext} disabled={!canProceed || isFetchingRates}>\n {isFetchingRates ? (\n <>\n <Spinner className=\"mr-2 h-4 w-4\" />\n {t('shipping_carriers.create.fetchingRates', 'Fetching rates...')}\n </>\n ) : (\n t('shipping_carriers.create.getQuotes', 'Get quotes')\n )}\n </Button>\n </div>\n </section>\n )\n}\n\n"],
5
+ "mappings": ";AAqEQ,SAqRI,UAnRA,KAFJ;AAnER,YAAY,WAAW;AACvB,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,eAAe;AACxB,SAAS,MAAM,aAAa,YAAY,iBAAiB;AACzD,SAAS,YAAY;AACrB,SAAS,qBAAqB;AAC9B,SAAS,qBAAqB;AAiC9B,MAAM,gBAA+B,CAAC,OAAO,OAAO,KAAK;AAElD,MAAM,gBAAgB,CAAC,UAA8B;AAC1D,QAAM;AAAA,IACJ;AAAA,IAAQ;AAAA,IAAa;AAAA,IAAU;AAAA,IAC/B;AAAA,IAAe;AAAA,IAAiB;AAAA,IAAa;AAAA,IAC7C;AAAA,IAAiB;AAAA,IACjB;AAAA,IAAqB;AAAA,IACrB;AAAA,IAAmB;AAAA,IAAe;AAAA,IAAyB;AAAA,IAC3D;AAAA,IAAgB;AAAA,IAAqB;AAAA,IAAkB;AAAA,IACvD;AAAA,IAAuB;AAAA,IAAyB;AAAA,IAAqB;AAAA,IACrE;AAAA,IACA;AAAA,IAAQ;AAAA,EACV,IAAI;AACJ,QAAM,IAAI,KAAK;AACf,QAAM,CAAC,aAAa,cAAc,IAAI,MAAM,SAAS,iBAAiB;AAEtE,SACE,qBAAC,aAAQ,WAAU,aACjB;AAAA,yBAAC,SAAI,WAAU,6BACb;AAAA,2BAAC,QACC;AAAA,4BAAC,cACC,8BAAC,aAAU,WAAU,aAClB,YAAE,2CAA2C,gBAAgB,GAChE,GACF;AAAA,QACA,oBAAC,eACC,8BAAC,iBAAc,QAAO,UAAS,SAAS,QAAQ,UAAU,gBAAgB,UAAU,iBAAiB,GACvG;AAAA,SACF;AAAA,MAEA,qBAAC,QACC;AAAA,4BAAC,cACC,8BAAC,aAAU,WAAU,aAClB,YAAE,gDAAgD,qBAAqB,GAC1E,GACF;AAAA,QACA,oBAAC,eACC,8BAAC,iBAAc,QAAO,QAAO,SAAS,aAAa,UAAU,qBAAqB,UAAU,iBAAiB,GAC/G;AAAA,SACF;AAAA,OACF;AAAA,IAEA,qBAAC,QACC;AAAA,0BAAC,cACC,8BAAC,aAAU,WAAU,aAClB,YAAE,6CAA6C,UAAU,GAC5D,GACF;AAAA,MACA,oBAAC,eACC,8BAAC,iBAAc,UAAoB,UAAU,kBAAkB,UAAU,iBAAiB,GAC5F;AAAA,OACF;AAAA,IAEA,qBAAC,SAAI,WAAU,6BACb;AAAA,2BAAC,QACC;AAAA,4BAAC,cACC,8BAAC,aAAU,WAAU,aAClB,YAAE,kDAAkD,gBAAgB,GACvE,GACF;AAAA,QACA,oBAAC,eACC,+BAAC,SAAI,WAAU,6BACb;AAAA,+BAAC,SAAI,WAAU,aACb;AAAA,gCAAC,WAAM,WAAU,6CACd,YAAE,wCAAwC,OAAO,GACpD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,OAAO,cAAc;AAAA,gBACrB,UAAU,CAAC,MAAM,sBAAsB,EAAE,GAAG,eAAe,OAAO,EAAE,OAAO,MAAM,CAAC;AAAA,gBAClF,UAAU;AAAA,gBACV,aAAY;AAAA,gBACZ,gBAAc,oBAAoB,QAAQ,OAAO;AAAA;AAAA,YACnD;AAAA,YACC,oBAAoB,QACnB,oBAAC,OAAE,WAAU,4BAA4B,8BAAoB,OAAM,IACjE;AAAA,aACN;AAAA,UACA,qBAAC,SAAI,WAAU,aACb;AAAA,gCAAC,WAAM,WAAU,6CACd,YAAE,wCAAwC,OAAO,GACpD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,OAAO,cAAc;AAAA,gBACrB,UAAU,CAAC,MAAM,sBAAsB,EAAE,GAAG,eAAe,OAAO,EAAE,OAAO,MAAM,CAAC;AAAA,gBAClF,UAAU;AAAA,gBACV,aAAY;AAAA,gBACZ,gBAAc,oBAAoB,QAAQ,OAAO;AAAA;AAAA,YACnD;AAAA,YACC,oBAAoB,QACnB,oBAAC,OAAE,WAAU,4BAA4B,8BAAoB,OAAM,IACjE;AAAA,aACN;AAAA,WACF,GACF;AAAA,SACF;AAAA,MAEA,qBAAC,QACC;AAAA,4BAAC,cACC,8BAAC,aAAU,WAAU,aAClB,YAAE,oDAAoD,kBAAkB,GAC3E,GACF;AAAA,QACA,oBAAC,eACC,+BAAC,SAAI,WAAU,6BACb;AAAA,+BAAC,SAAI,WAAU,aACb;AAAA,gCAAC,WAAM,WAAU,6CACd,YAAE,wCAAwC,OAAO,GACpD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,OAAO,gBAAgB;AAAA,gBACvB,UAAU,CAAC,MAAM,wBAAwB,EAAE,GAAG,iBAAiB,OAAO,EAAE,OAAO,MAAM,CAAC;AAAA,gBACtF,UAAU;AAAA,gBACV,aAAY;AAAA,gBACZ,gBAAc,sBAAsB,QAAQ,OAAO;AAAA;AAAA,YACrD;AAAA,YACC,sBAAsB,QACrB,oBAAC,OAAE,WAAU,4BAA4B,gCAAsB,OAAM,IACnE;AAAA,aACN;AAAA,UACA,qBAAC,SAAI,WAAU,aACb;AAAA,gCAAC,WAAM,WAAU,6CACd,YAAE,wCAAwC,OAAO,GACpD;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,OAAO,gBAAgB;AAAA,gBACvB,UAAU,CAAC,MAAM,wBAAwB,EAAE,GAAG,iBAAiB,OAAO,EAAE,OAAO,MAAM,CAAC;AAAA,gBACtF,UAAU;AAAA,gBACV,aAAY;AAAA,gBACZ,gBAAc,sBAAsB,QAAQ,OAAO;AAAA;AAAA,YACrD;AAAA,YACC,sBAAsB,QACrB,oBAAC,OAAE,WAAU,4BAA4B,gCAAsB,OAAM,IACnE;AAAA,aACN;AAAA,WACF,GACF;AAAA,SACF;AAAA,OACF;AAAA,IAEA,qBAAC,QACC;AAAA,0BAAC,cACC,8BAAC,aAAU,WAAU,aAClB,YAAE,qDAAqD,oBAAoB,GAC9E,GACF;AAAA,MACA,oBAAC,eACC,+BAAC,SAAI,WAAU,aACb;AAAA,4BAAC,WAAM,WAAU,6CACd,YAAE,mDAAmD,sDAAsD,GAC9G;AAAA,QACA;AAAA,UAAC;AAAA;AAAA,YACC,OAAO,oBAAoB;AAAA,YAC3B,eAAe,CAAC,UAAU,yBAAyB,SAAS,EAAE;AAAA,YAC9D,UAAU;AAAA,YAEV;AAAA,kCAAC,iBAAc,MAAK,MAClB,8BAAC,eAAY,aAAa,EAAE,qDAAqD,0BAA0B,GAAG,GAChH;AAAA,cACA,qBAAC,iBACC;AAAA,oCAAC,cAAW,OAAM,iBAAiB,YAAE,2DAA2D,eAAe,GAAE;AAAA,gBACjH,oBAAC,cAAW,OAAM,OAAO,YAAE,iDAAiD,2BAA2B,GAAE;AAAA,gBACzG,oBAAC,cAAW,OAAM,aAAa,YAAE,uDAAuD,WAAW,GAAE;AAAA,iBACvG;AAAA;AAAA;AAAA,QACF;AAAA,SACF,GACF;AAAA,OACF;AAAA,KAEE,qBAAqB,mBAAmB,qBAAqB,UAC7D,qBAAC,QACC;AAAA,0BAAC,cACC,8BAAC,aAAU,WAAU,aAClB,YAAE,iDAAiD,yBAAyB,GAC/E,GACF;AAAA,MACA,qBAAC,eAAY,WAAU,aACpB;AAAA,uBACC,qBAAC,SAAI,WAAU,gEACb;AAAA,8BAAC,UAAK,WAAU,kDACb,YAAE,gDAAgD,WAAW,GAChE;AAAA,UACA,oBAAC,UAAK,WAAU,yBAAyB,uBAAY;AAAA,UACrD;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,WAAU;AAAA,cACV,SAAS,MAAM,oBAAoB,EAAE;AAAA,cACrC,UAAU;AAAA,cAET,YAAE,8CAA8C,OAAO;AAAA;AAAA,UAC1D;AAAA,WACF;AAAA,QAGF,qBAAC,SAAI,WAAU,cACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,eAAe,EAAE,OAAO,KAAK;AAAA,cAC9C,WAAW,CAAC,MAAM;AAChB,oBAAI,EAAE,QAAQ,SAAS;AACrB,oBAAE,eAAe;AACjB,wCAAsB,WAAW;AAAA,gBACnC;AAAA,cACF;AAAA,cACA,UAAU;AAAA,cACV,aAAa,EAAE,gDAAgD,uDAAuD;AAAA;AAAA,UACxH;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,MAAK;AAAA,cACL,SAAS,MAAM,sBAAsB,WAAW;AAAA,cAChD,UAAU,mBAAmB,2BAA2B,YAAY,KAAK,EAAE,WAAW;AAAA,cAErF,oCACC,oBAAC,WAAQ,WAAU,WAAU,IAE7B,EAAE,gDAAgD,QAAQ;AAAA;AAAA,UAE9D;AAAA,WACF;AAAA,QAEC,sBACC,oBAAC,OAAE,WAAU,4BAA4B,8BAAmB;AAAA,QAG7D,cAAc,SAAS,KACtB,oBAAC,QAAG,WAAU,4DACX,wBAAc,IAAI,CAAC,UAClB,oBAAC,QACC;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,WAAW,8CAA8C,gBAAgB,MAAM,KAAK,6BAA6B,EAAE;AAAA,YACnH,SAAS,MAAM,oBAAoB,MAAM,EAAE;AAAA,YAC3C,UAAU;AAAA,YAEV;AAAA,kCAAC,UAAK,WAAU,kBAAkB,gBAAM,MAAK;AAAA,cAC7C,oBAAC,UAAK,WAAU,iCACb,WAAC,MAAM,QAAQ,MAAM,MAAM,MAAM,UAAU,EAAE,OAAO,OAAO,EAAE,KAAK,IAAI,GACzE;AAAA;AAAA;AAAA,QACF,KAXO,MAAM,EAYf,CACD,GACH;AAAA,QAGD,CAAC,2BAA2B,cAAc,WAAW,KAAK,qBAAqB,CAAC,sBAC/E,oBAAC,OAAE,WAAU,iCACV,YAAE,oDAAoD,2CAA2C,GACpG;AAAA,SAEJ;AAAA,OACF;AAAA,IAGF,qBAAC,QACC;AAAA,0BAAC,cACC,8BAAC,aAAU,WAAU,aAClB,YAAE,gDAAgD,cAAc,GACnE,GACF;AAAA,MACA,oBAAC,eACC,8BAAC,SAAI,WAAU,cACZ,wBAAc,IAAI,CAAC,QAClB;AAAA,QAAC;AAAA;AAAA,UAEC,MAAK;AAAA,UACL,SAAS,gBAAgB,MAAM,YAAY;AAAA,UAC3C,MAAK;AAAA,UACL,SAAS,MAAM,oBAAoB,GAAG;AAAA,UACtC,UAAU;AAAA,UAET,cAAI,YAAY;AAAA;AAAA,QAPZ;AAAA,MAQP,CACD,GACH,GACF;AAAA,OACF;AAAA,IAEA,qBAAC,SAAI,WAAU,8BACb;AAAA,0BAAC,UAAO,MAAK,UAAS,SAAQ,WAAU,SAAS,QAAQ,UAAU,iBAChE,YAAE,iCAAiC,MAAM,GAC5C;AAAA,MACA,oBAAC,UAAO,MAAK,UAAS,SAAS,QAAQ,UAAU,CAAC,cAAc,iBAC7D,4BACC,iCACE;AAAA,4BAAC,WAAQ,WAAU,gBAAe;AAAA,QACjC,EAAE,0CAA0C,mBAAmB;AAAA,SAClE,IAEA,EAAE,sCAAsC,YAAY,GAExD;AAAA,OACF;AAAA,KACF;AAEJ;",
6
6
  "names": []
7
7
  }
@@ -8,6 +8,13 @@ import { normalizeCustomFieldValues } from "@open-mercato/shared/lib/custom-fiel
8
8
  import { apiCall } from "@open-mercato/ui/backend/utils/apiCall";
9
9
  import { LookupSelect } from "@open-mercato/ui/backend/inputs";
10
10
  import { Button } from "@open-mercato/ui/primitives/button";
11
+ import {
12
+ Select,
13
+ SelectContent,
14
+ SelectItem,
15
+ SelectTrigger,
16
+ SelectValue
17
+ } from "@open-mercato/ui/primitives/select";
11
18
  import { AttachmentsSection, TagsSection } from "@open-mercato/ui/backend/detail";
12
19
  import { E } from "../../../generated/entities.ids.generated.js";
13
20
  import { useT } from "@open-mercato/shared/lib/i18n/context";
@@ -216,13 +223,12 @@ function TeamMemberForm(props) {
216
223
  )
217
224
  ] }),
218
225
  /* @__PURE__ */ jsxs(
219
- "select",
226
+ Select,
220
227
  {
221
- className: "w-full h-9 rounded border px-2 text-sm",
222
- value: currentValue,
223
- onChange: (event) => {
224
- const nextValue = event.target.value || void 0;
225
- const nextTeamId = event.target.value || null;
228
+ value: currentValue || void 0,
229
+ onValueChange: (value2) => {
230
+ const nextValue = value2 || void 0;
231
+ const nextTeamId = value2 || null;
226
232
  setValue(nextValue);
227
233
  setSelectedTeamId(nextTeamId);
228
234
  if (!setFormValue) return;
@@ -233,11 +239,10 @@ function TeamMemberForm(props) {
233
239
  setFormValue("roleIds", nextRoleIds);
234
240
  }
235
241
  },
236
- "data-crud-focus-target": "",
237
242
  disabled,
238
243
  children: [
239
- /* @__PURE__ */ jsx("option", { value: "", children: translate("ui.forms.select.emptyOption", "\u2014") }),
240
- teamOptions.map((option) => /* @__PURE__ */ jsx("option", { value: option.value, children: option.label }, option.value))
244
+ /* @__PURE__ */ jsx(SelectTrigger, { "data-crud-focus-target": "", children: /* @__PURE__ */ jsx(SelectValue, { placeholder: translate("ui.forms.select.emptyOption", "\u2014") }) }),
245
+ /* @__PURE__ */ jsx(SelectContent, { children: teamOptions.map((option) => /* @__PURE__ */ jsx(SelectItem, { value: option.value, children: option.label }, option.value)) })
241
246
  ]
242
247
  }
243
248
  )