@endora-commerce/mod-inventory 0.100.0

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 (223) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -0
  3. package/dist/admin/api/warehouses-client.d.ts +22 -0
  4. package/dist/admin/api/warehouses-client.d.ts.map +1 -0
  5. package/dist/admin/api/warehouses-client.js +32 -0
  6. package/dist/admin/api/warehouses-client.js.map +1 -0
  7. package/dist/admin/index.d.ts +43 -0
  8. package/dist/admin/index.d.ts.map +1 -0
  9. package/dist/admin/index.js +190 -0
  10. package/dist/admin/index.js.map +1 -0
  11. package/dist/admin/pages/AvailabilityNotificationsPage.d.ts +15 -0
  12. package/dist/admin/pages/AvailabilityNotificationsPage.d.ts.map +1 -0
  13. package/dist/admin/pages/AvailabilityNotificationsPage.js +111 -0
  14. package/dist/admin/pages/AvailabilityNotificationsPage.js.map +1 -0
  15. package/dist/admin/pages/InventoryPage.d.ts +17 -0
  16. package/dist/admin/pages/InventoryPage.d.ts.map +1 -0
  17. package/dist/admin/pages/InventoryPage.js +135 -0
  18. package/dist/admin/pages/InventoryPage.js.map +1 -0
  19. package/dist/admin/pages/LowStockPage.d.ts +16 -0
  20. package/dist/admin/pages/LowStockPage.d.ts.map +1 -0
  21. package/dist/admin/pages/LowStockPage.js +61 -0
  22. package/dist/admin/pages/LowStockPage.js.map +1 -0
  23. package/dist/admin/pages/StockImportWizard.d.ts +17 -0
  24. package/dist/admin/pages/StockImportWizard.d.ts.map +1 -0
  25. package/dist/admin/pages/StockImportWizard.js +111 -0
  26. package/dist/admin/pages/StockImportWizard.js.map +1 -0
  27. package/dist/admin/pages/WarehouseEditor.d.ts +12 -0
  28. package/dist/admin/pages/WarehouseEditor.d.ts.map +1 -0
  29. package/dist/admin/pages/WarehouseEditor.js +194 -0
  30. package/dist/admin/pages/WarehouseEditor.js.map +1 -0
  31. package/dist/admin/pages/WarehousesList.d.ts +12 -0
  32. package/dist/admin/pages/WarehousesList.d.ts.map +1 -0
  33. package/dist/admin/pages/WarehousesList.js +69 -0
  34. package/dist/admin/pages/WarehousesList.js.map +1 -0
  35. package/dist/admin/zones/ChannelWarehouses.d.ts +49 -0
  36. package/dist/admin/zones/ChannelWarehouses.d.ts.map +1 -0
  37. package/dist/admin/zones/ChannelWarehouses.js +109 -0
  38. package/dist/admin/zones/ChannelWarehouses.js.map +1 -0
  39. package/dist/backend/demo/reset.d.ts +18 -0
  40. package/dist/backend/demo/reset.d.ts.map +1 -0
  41. package/dist/backend/demo/reset.js +20 -0
  42. package/dist/backend/demo/reset.js.map +1 -0
  43. package/dist/backend/demo/rows.d.ts +38 -0
  44. package/dist/backend/demo/rows.d.ts.map +1 -0
  45. package/dist/backend/demo/rows.js +38 -0
  46. package/dist/backend/demo/rows.js.map +1 -0
  47. package/dist/backend/demo/seed.d.ts +26 -0
  48. package/dist/backend/demo/seed.d.ts.map +1 -0
  49. package/dist/backend/demo/seed.js +65 -0
  50. package/dist/backend/demo/seed.js.map +1 -0
  51. package/dist/backend/email-templates/transactional-defaults.d.ts +11 -0
  52. package/dist/backend/email-templates/transactional-defaults.d.ts.map +1 -0
  53. package/dist/backend/email-templates/transactional-defaults.js +49 -0
  54. package/dist/backend/email-templates/transactional-defaults.js.map +1 -0
  55. package/dist/backend/entities/availability-notification.entity.d.ts +49 -0
  56. package/dist/backend/entities/availability-notification.entity.d.ts.map +1 -0
  57. package/dist/backend/entities/availability-notification.entity.js +93 -0
  58. package/dist/backend/entities/availability-notification.entity.js.map +1 -0
  59. package/dist/backend/entities/inventory-threshold.entity.d.ts +24 -0
  60. package/dist/backend/entities/inventory-threshold.entity.d.ts.map +1 -0
  61. package/dist/backend/entities/inventory-threshold.entity.js +61 -0
  62. package/dist/backend/entities/inventory-threshold.entity.js.map +1 -0
  63. package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.d.ts +15 -0
  64. package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.d.ts.map +1 -0
  65. package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.js +51 -0
  66. package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.js.map +1 -0
  67. package/dist/backend/entities/stock-allocation.entity.d.ts +22 -0
  68. package/dist/backend/entities/stock-allocation.entity.d.ts.map +1 -0
  69. package/dist/backend/entities/stock-allocation.entity.js +69 -0
  70. package/dist/backend/entities/stock-allocation.entity.js.map +1 -0
  71. package/dist/backend/entities/stock-level.entity.d.ts +24 -0
  72. package/dist/backend/entities/stock-level.entity.d.ts.map +1 -0
  73. package/dist/backend/entities/stock-level.entity.js +74 -0
  74. package/dist/backend/entities/stock-level.entity.js.map +1 -0
  75. package/dist/backend/entities/warehouse-channel-assignment.entity.d.ts +17 -0
  76. package/dist/backend/entities/warehouse-channel-assignment.entity.d.ts.map +1 -0
  77. package/dist/backend/entities/warehouse-channel-assignment.entity.js +60 -0
  78. package/dist/backend/entities/warehouse-channel-assignment.entity.js.map +1 -0
  79. package/dist/backend/entities/warehouse.entity.d.ts +37 -0
  80. package/dist/backend/entities/warehouse.entity.d.ts.map +1 -0
  81. package/dist/backend/entities/warehouse.entity.js +90 -0
  82. package/dist/backend/entities/warehouse.entity.js.map +1 -0
  83. package/dist/backend/index.d.ts +139 -0
  84. package/dist/backend/index.d.ts.map +1 -0
  85. package/dist/backend/index.js +351 -0
  86. package/dist/backend/index.js.map +1 -0
  87. package/dist/backend/plugin.d.ts +113 -0
  88. package/dist/backend/plugin.d.ts.map +1 -0
  89. package/dist/backend/plugin.js +75 -0
  90. package/dist/backend/plugin.js.map +1 -0
  91. package/dist/backend/prompt-tools.d.ts +23 -0
  92. package/dist/backend/prompt-tools.d.ts.map +1 -0
  93. package/dist/backend/prompt-tools.js +77 -0
  94. package/dist/backend/prompt-tools.js.map +1 -0
  95. package/dist/backend/routes.admin.d.ts +62 -0
  96. package/dist/backend/routes.admin.d.ts.map +1 -0
  97. package/dist/backend/routes.admin.js +383 -0
  98. package/dist/backend/routes.admin.js.map +1 -0
  99. package/dist/backend/routes.d.ts +40 -0
  100. package/dist/backend/routes.d.ts.map +1 -0
  101. package/dist/backend/routes.js +263 -0
  102. package/dist/backend/routes.js.map +1 -0
  103. package/dist/backend/services/audit-references.d.ts +15 -0
  104. package/dist/backend/services/audit-references.d.ts.map +1 -0
  105. package/dist/backend/services/audit-references.js +27 -0
  106. package/dist/backend/services/audit-references.js.map +1 -0
  107. package/dist/backend/services/availability-notification-service.d.ts +155 -0
  108. package/dist/backend/services/availability-notification-service.d.ts.map +1 -0
  109. package/dist/backend/services/availability-notification-service.js +363 -0
  110. package/dist/backend/services/availability-notification-service.js.map +1 -0
  111. package/dist/backend/services/availability-worker.d.ts +57 -0
  112. package/dist/backend/services/availability-worker.d.ts.map +1 -0
  113. package/dist/backend/services/availability-worker.js +135 -0
  114. package/dist/backend/services/availability-worker.js.map +1 -0
  115. package/dist/backend/services/csv-stock-importer.d.ts +52 -0
  116. package/dist/backend/services/csv-stock-importer.d.ts.map +1 -0
  117. package/dist/backend/services/csv-stock-importer.js +154 -0
  118. package/dist/backend/services/csv-stock-importer.js.map +1 -0
  119. package/dist/backend/services/display-band-resolver.d.ts +19 -0
  120. package/dist/backend/services/display-band-resolver.d.ts.map +1 -0
  121. package/dist/backend/services/display-band-resolver.js +21 -0
  122. package/dist/backend/services/display-band-resolver.js.map +1 -0
  123. package/dist/backend/services/effective-fulfilment-strategy.d.ts +16 -0
  124. package/dist/backend/services/effective-fulfilment-strategy.d.ts.map +1 -0
  125. package/dist/backend/services/effective-fulfilment-strategy.js +16 -0
  126. package/dist/backend/services/effective-fulfilment-strategy.js.map +1 -0
  127. package/dist/backend/services/fulfilment-strategy-resolver.d.ts +13 -0
  128. package/dist/backend/services/fulfilment-strategy-resolver.d.ts.map +1 -0
  129. package/dist/backend/services/fulfilment-strategy-resolver.js +13 -0
  130. package/dist/backend/services/fulfilment-strategy-resolver.js.map +1 -0
  131. package/dist/backend/services/inventory-read-port.d.ts +65 -0
  132. package/dist/backend/services/inventory-read-port.d.ts.map +1 -0
  133. package/dist/backend/services/inventory-read-port.js +168 -0
  134. package/dist/backend/services/inventory-read-port.js.map +1 -0
  135. package/dist/backend/services/inventory-reservation-apply-port.d.ts +62 -0
  136. package/dist/backend/services/inventory-reservation-apply-port.d.ts.map +1 -0
  137. package/dist/backend/services/inventory-reservation-apply-port.js +134 -0
  138. package/dist/backend/services/inventory-reservation-apply-port.js.map +1 -0
  139. package/dist/backend/services/low-stock-alert-service.d.ts +87 -0
  140. package/dist/backend/services/low-stock-alert-service.d.ts.map +1 -0
  141. package/dist/backend/services/low-stock-alert-service.js +164 -0
  142. package/dist/backend/services/low-stock-alert-service.js.map +1 -0
  143. package/dist/backend/services/product-threshold-write.service.d.ts +38 -0
  144. package/dist/backend/services/product-threshold-write.service.d.ts.map +1 -0
  145. package/dist/backend/services/product-threshold-write.service.js +80 -0
  146. package/dist/backend/services/product-threshold-write.service.js.map +1 -0
  147. package/dist/backend/services/stock-import.service.d.ts +43 -0
  148. package/dist/backend/services/stock-import.service.d.ts.map +1 -0
  149. package/dist/backend/services/stock-import.service.js +124 -0
  150. package/dist/backend/services/stock-import.service.js.map +1 -0
  151. package/dist/backend/services/stock-level-service.d.ts +146 -0
  152. package/dist/backend/services/stock-level-service.d.ts.map +1 -0
  153. package/dist/backend/services/stock-level-service.js +489 -0
  154. package/dist/backend/services/stock-level-service.js.map +1 -0
  155. package/dist/backend/services/threshold-admin-service.d.ts +73 -0
  156. package/dist/backend/services/threshold-admin-service.d.ts.map +1 -0
  157. package/dist/backend/services/threshold-admin-service.js +167 -0
  158. package/dist/backend/services/threshold-admin-service.js.map +1 -0
  159. package/dist/backend/services/threshold-resolver.d.ts +23 -0
  160. package/dist/backend/services/threshold-resolver.d.ts.map +1 -0
  161. package/dist/backend/services/threshold-resolver.js +29 -0
  162. package/dist/backend/services/threshold-resolver.js.map +1 -0
  163. package/dist/backend/services/threshold-settings-mirror.d.ts +55 -0
  164. package/dist/backend/services/threshold-settings-mirror.d.ts.map +1 -0
  165. package/dist/backend/services/threshold-settings-mirror.js +84 -0
  166. package/dist/backend/services/threshold-settings-mirror.js.map +1 -0
  167. package/dist/backend/services/warehouse-channel-reconciler.d.ts +19 -0
  168. package/dist/backend/services/warehouse-channel-reconciler.d.ts.map +1 -0
  169. package/dist/backend/services/warehouse-channel-reconciler.js +65 -0
  170. package/dist/backend/services/warehouse-channel-reconciler.js.map +1 -0
  171. package/dist/backend/services/warehouse-channel-service.d.ts +57 -0
  172. package/dist/backend/services/warehouse-channel-service.d.ts.map +1 -0
  173. package/dist/backend/services/warehouse-channel-service.js +205 -0
  174. package/dist/backend/services/warehouse-channel-service.js.map +1 -0
  175. package/dist/backend/services/warehouse-country-reference.d.ts +14 -0
  176. package/dist/backend/services/warehouse-country-reference.d.ts.map +1 -0
  177. package/dist/backend/services/warehouse-country-reference.js +27 -0
  178. package/dist/backend/services/warehouse-country-reference.js.map +1 -0
  179. package/dist/backend/services/warehouse-service.d.ts +86 -0
  180. package/dist/backend/services/warehouse-service.d.ts.map +1 -0
  181. package/dist/backend/services/warehouse-service.js +267 -0
  182. package/dist/backend/services/warehouse-service.js.map +1 -0
  183. package/dist/manifest.d.ts +219 -0
  184. package/dist/manifest.d.ts.map +1 -0
  185. package/dist/manifest.js +377 -0
  186. package/dist/manifest.js.map +1 -0
  187. package/dist/migrations/20260503T182812_inventory_workflow.d.ts +39 -0
  188. package/dist/migrations/20260503T182812_inventory_workflow.d.ts.map +1 -0
  189. package/dist/migrations/20260503T182812_inventory_workflow.js +205 -0
  190. package/dist/migrations/20260503T182812_inventory_workflow.js.map +1 -0
  191. package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.d.ts +14 -0
  192. package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.d.ts.map +1 -0
  193. package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.js +18 -0
  194. package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.js.map +1 -0
  195. package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.d.ts +28 -0
  196. package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.d.ts.map +1 -0
  197. package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.js +48 -0
  198. package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.js.map +1 -0
  199. package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.d.ts +44 -0
  200. package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.d.ts.map +1 -0
  201. package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.js +81 -0
  202. package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.js.map +1 -0
  203. package/dist/migrations/20260830T182139_inventory_organization_attribution.d.ts +109 -0
  204. package/dist/migrations/20260830T182139_inventory_organization_attribution.d.ts.map +1 -0
  205. package/dist/migrations/20260830T182139_inventory_organization_attribution.js +178 -0
  206. package/dist/migrations/20260830T182139_inventory_organization_attribution.js.map +1 -0
  207. package/dist/migrations/20260912T125716_inventory_organization_warehouses.d.ts +34 -0
  208. package/dist/migrations/20260912T125716_inventory_organization_warehouses.d.ts.map +1 -0
  209. package/dist/migrations/20260912T125716_inventory_organization_warehouses.js +50 -0
  210. package/dist/migrations/20260912T125716_inventory_organization_warehouses.js.map +1 -0
  211. package/dist/migrations/index.d.ts +32 -0
  212. package/dist/migrations/index.d.ts.map +1 -0
  213. package/dist/migrations/index.js +39 -0
  214. package/dist/migrations/index.js.map +1 -0
  215. package/dist/ports/index.d.ts +183 -0
  216. package/dist/ports/index.d.ts.map +1 -0
  217. package/dist/ports/index.js +2 -0
  218. package/dist/ports/index.js.map +1 -0
  219. package/docs/inventory.md +177 -0
  220. package/i18n/en.json +32 -0
  221. package/i18n/pl.json +32 -0
  222. package/package.json +105 -0
  223. package/tailwind.css +14 -0
@@ -0,0 +1,135 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState, } from 'react';
3
+ import { Link, useSearchParams } from 'react-router-dom';
4
+ import { AlertCircle, Search, Upload } from 'lucide-react';
5
+ import { ApiError, apiClient, cn, usePageSizePreference, useSurfaceVisibility } from '@endora-commerce/admin-kit/lib';
6
+ import { PaginationFooter } from '@endora-commerce/admin-kit/components';
7
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
8
+ /**
9
+ * Inventory landing — feature 010 / US2.
10
+ *
11
+ * KPI strip backed by `GET /api/v1/admin/inventory`.
12
+ * Per-product roster from `GET /api/v1/admin/inventory/levels`.
13
+ * Per-row edit lands in the product editor's Inventory tab; the import
14
+ * wizard ships in US7.
15
+ */
16
+ export function InventoryPage() {
17
+ const t = useTranslation('core');
18
+ /**
19
+ * The screen's own gate (2026-08-29), on the codes its routes now enforce.
20
+ *
21
+ * `inventory` used to borrow `orders:read` for every read and `catalog:write`
22
+ * for every write, so this page had no permission of its own to check and the
23
+ * sidebar entry beside it carried another module's code. Both moved together;
24
+ * hiding the screen rather than letting it 403 is the treatment the sidebar,
25
+ * the palette and the dashboard already apply to a denied destination, and
26
+ * `AppShell.tsx`'s `PALETTE_ITEMS` comment argues it at length. The module
27
+ * half is asked too, because the admin router carries no guard of its own: a
28
+ * module the platform is not running must contribute no surface at all
29
+ * (Constitution XVII item 5), and a permission gate alone leaves this screen
30
+ * rendering and answering 503. For this module that second axis is a real
31
+ * operator switch — `inventory.enabled` — and not only platform availability.
32
+ *
33
+ * `useSurfaceVisibility` is the predicate the sidebar, the palette and the
34
+ * dashboard already share, so the two axes are one expression rather than two
35
+ * that can drift.
36
+ */
37
+ const isVisible = useSurfaceVisibility();
38
+ const canRead = isVisible({ module: 'inventory', requiredPermission: 'inventory:read' });
39
+ /**
40
+ * The write half, which is new rather than moved: until this change there was
41
+ * no read-only role to have, because the import link went to a screen gated on
42
+ * `catalog:write` while this page was gated on `orders:read` — two codes
43
+ * nobody grants together on purpose.
44
+ */
45
+ const canWrite = isVisible({ module: 'inventory', requiredPermission: 'inventory:write' });
46
+ const [searchParams] = useSearchParams();
47
+ const [kpis, setKpis] = useState(null);
48
+ const [rows, setRows] = useState([]);
49
+ const [total, setTotal] = useState(0);
50
+ const [loading, setLoading] = useState(true);
51
+ const [error, setError] = useState(null);
52
+ const [query, setQuery] = useState('');
53
+ const [statusFilter, setStatusFilter] = useState(() => {
54
+ const fromUrl = searchParams.get('stock');
55
+ return fromUrl === 'low' || fromUrl === 'out' ? fromUrl : 'all';
56
+ });
57
+ const { pageSize, setPageSize } = usePageSizePreference('inventory-levels');
58
+ const [page, setPage] = useState(0);
59
+ // Debounce the text query so typing doesn't fire a fetch on every
60
+ // keystroke. 250 ms feels live but coalesces typing bursts.
61
+ const [debouncedQuery, setDebouncedQuery] = useState(query);
62
+ useEffect(() => {
63
+ const id = window.setTimeout(() => setDebouncedQuery(query), 250);
64
+ return () => window.clearTimeout(id);
65
+ }, [query]);
66
+ const refresh = useCallback(async () => {
67
+ // A page that renders nothing has no reason to ask the API a question it
68
+ // will be refused.
69
+ if (!canRead) {
70
+ setLoading(false);
71
+ return;
72
+ }
73
+ setLoading(true);
74
+ setError(null);
75
+ try {
76
+ const params = new URLSearchParams();
77
+ params.set('page', String(page));
78
+ params.set('pageSize', String(pageSize));
79
+ const trimmed = debouncedQuery.trim();
80
+ if (trimmed)
81
+ params.set('q', trimmed);
82
+ if (statusFilter === 'low')
83
+ params.set('low', '1');
84
+ else if (statusFilter === 'out')
85
+ params.set('out', '1');
86
+ const [kpiRes, rosterRes] = await Promise.all([
87
+ apiClient.get('/api/v1/admin/inventory'),
88
+ apiClient.get(`/api/v1/admin/inventory/levels?${params.toString()}`),
89
+ ]);
90
+ setKpis(kpiRes.data);
91
+ setRows(rosterRes.items);
92
+ setTotal(rosterRes.total);
93
+ }
94
+ catch (err) {
95
+ setError(err instanceof ApiError ? err.envelope.error.message : t('inventory.error.load'));
96
+ }
97
+ finally {
98
+ setLoading(false);
99
+ }
100
+ }, [canRead, page, pageSize, debouncedQuery, statusFilter, t]);
101
+ useEffect(() => {
102
+ void refresh();
103
+ }, [refresh]);
104
+ // Reset to the first page whenever the result-shaping inputs change so
105
+ // the user never lands on an out-of-range page.
106
+ useEffect(() => {
107
+ setPage(0);
108
+ }, [pageSize, debouncedQuery, statusFilter]);
109
+ // Filters are server-side now; rows arrive pre-filtered and pre-paginated.
110
+ const filtered = rows;
111
+ if (!canRead) {
112
+ return _jsx("div", { className: "b2b-page", children: t('inventory.noPermission') });
113
+ }
114
+ return (_jsxs("div", { className: "b2b-page b2b-page--wide", children: [_jsxs("div", { className: "b2b-page-head", children: [_jsxs("div", { className: "b2b-grow", children: [_jsx("div", { className: "b2b-page-head__title", children: t('inventory.page.title') }), _jsxs("div", { className: "b2b-page-head__sub", children: [t('inventory.page.subPrefix'), ' ', _jsx("code", { className: "b2b-mono", children: "stock_levels" }), t('inventory.page.subSuffix')] })] }), _jsx("div", { className: "b2b-page-head__actions", children: canWrite ? (_jsxs(Link, { to: "/inventory/import", className: "b2b-btn b2b-btn--default b2b-btn--sm", style: { display: 'inline-flex', alignItems: 'center', gap: 6 }, children: [_jsx(Upload, { size: 13 }), " ", t('inventory.action.import')] })) : null })] }), error ? (_jsx("div", { className: "b2b-card", style: {
115
+ background: 'var(--danger-soft)',
116
+ color: 'var(--danger-soft-fg)',
117
+ padding: 12,
118
+ marginBottom: 16,
119
+ border: '1px solid hsl(8 80% 85%)',
120
+ }, children: error })) : null, _jsxs("div", { className: "b2b-row", style: { gap: 16, marginBottom: 16 }, children: [_jsx(Stat, { label: t('inventory.stat.tracked'), value: (kpis?.totalProductsTracked ?? 0).toLocaleString() }), _jsx(Stat, { label: t('inventory.stat.totalOnHand'), value: (kpis?.totalOnHand ?? 0).toLocaleString() }), _jsx(Stat, { label: t('inventory.stat.outOfStock'), value: String(kpis?.outOfStockCount ?? 0), tone: "danger" }), _jsx(Stat, { label: t('inventory.stat.lowStock'), value: String(kpis?.lowStockCount ?? 0), tone: "warn" })] }), kpis && kpis.perWarehouseTotals.length > 0 ? (_jsxs("div", { className: "b2b-card", style: { marginBottom: 16 }, children: [_jsx("div", { className: "b2b-card__head", children: _jsx("h2", { children: t('inventory.perWarehouseTotals') }) }), _jsx("div", { className: "b2b-card__body", children: _jsx("div", { className: "b2b-row", style: { gap: 24, flexWrap: 'wrap' }, children: kpis.perWarehouseTotals.map((row) => (_jsxs("div", { children: [_jsx("div", { className: "b2b-muted", style: { fontSize: 11, textTransform: 'uppercase' }, children: row.warehouseCode }), _jsx("div", { style: { fontSize: 20, fontWeight: 600 }, children: row.onHand.toLocaleString() })] }, row.warehouseId))) }) })] })) : null, _jsxs("div", { className: "b2b-card", children: [_jsxs("div", { className: "b2b-filterbar", children: [_jsx("div", { className: "b2b-filterbar__search", children: _jsxs("div", { className: "b2b-input-wrap", children: [_jsx(Search, { size: 16, className: "lead" }), _jsx("input", { className: "b2b-field b2b-field--addon", placeholder: t('inventory.search.placeholder'), value: query, onChange: (e) => setQuery(e.target.value) })] }) }), _jsx(Chip, { icon: _jsx(AlertCircle, { size: 12 }), active: statusFilter === 'low', label: t('inventory.stat.lowStock'), onClick: () => setStatusFilter((s) => (s === 'low' ? 'all' : 'low')) }), _jsx(Chip, { icon: _jsx(AlertCircle, { size: 12 }), active: statusFilter === 'out', label: t('inventory.stat.outOfStock'), onClick: () => setStatusFilter((s) => (s === 'out' ? 'all' : 'out')) })] }), _jsx("div", { className: "b2b-card__body b2b-card__body--flush", children: loading ? (_jsx("div", { style: { padding: 32, color: 'var(--fg-muted)', fontSize: 13 }, children: t('inventory.loading') })) : filtered.length === 0 ? (_jsxs("div", { className: "b2b-empty", children: [_jsx("div", { className: "b2b-empty__icon", children: _jsx(Search, { size: 20 }) }), _jsx("div", { className: "b2b-empty__title", children: t('inventory.empty') })] })) : (_jsxs("table", { className: "b2b-tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: t('inventory.column.product') }), _jsx("th", { children: t('inventory.column.sku') }), _jsx("th", { className: "num", children: t('inventory.column.cumulativeOnHand') }), _jsx("th", { children: t('inventory.column.perWarehouse') }), _jsx("th", { children: t('inventory.column.displayBand') }), _jsx("th", {})] }) }), _jsx("tbody", { children: filtered.map((r) => (_jsxs("tr", { children: [_jsx("td", { children: r.productName }), _jsx("td", { children: _jsx("span", { className: "b2b-mono", style: { fontSize: 12, color: 'var(--fg-muted)' }, children: r.productSku }) }), _jsx("td", { className: "num b2b-tabular", style: { fontWeight: 600 }, children: r.cumulativeOnHand.toLocaleString() }), _jsx("td", { children: _jsx("div", { className: "b2b-row", style: { gap: 8, flexWrap: 'wrap' }, children: r.perWarehouse.map((w) => (_jsxs("span", { className: "b2b-badge b2b-badge--muted", title: w.warehouseId, children: [w.warehouseCode, ": ", w.onHand.toLocaleString()] }, w.warehouseId))) }) }), _jsx("td", { children: _jsx("span", { className: cn('b2b-badge', r.displayBand === 'high' && 'b2b-badge--success', r.displayBand === 'medium' && 'b2b-badge--warn', r.displayBand === 'low' && 'b2b-badge--warn', r.displayBand === 'out_of_stock' && 'b2b-badge--danger', r.displayBand === 'available' && 'b2b-badge--muted'), children: r.displayBand }) }), _jsx("td", { className: "actions", children: _jsx(Link, { to: `/catalog/products/${r.productId}`, className: "b2b-btn b2b-btn--ghost b2b-btn--sm", children: t('inventory.action.editStock') }) })] }, r.productId))) })] })) }), _jsx(PaginationFooter, { page: page, pageSize: pageSize, total: total, onPageSizeChange: setPageSize, onPrev: () => setPage((p) => Math.max(0, p - 1)), onNext: () => setPage((p) => p + 1) })] })] }));
121
+ }
122
+ function Stat({ label, value, tone, }) {
123
+ const color = tone === 'danger' ? 'var(--danger)' : tone === 'warn' ? 'var(--warn)' : 'var(--fg)';
124
+ return (_jsxs("div", { className: "b2b-card", style: { flex: 1, padding: 16 }, children: [_jsx("div", { className: "b2b-muted", style: { fontSize: 11, textTransform: 'uppercase', letterSpacing: '0.06em' }, children: label }), _jsx("div", { style: { fontSize: 26, fontWeight: 600, marginTop: 4, color }, children: value })] }));
125
+ }
126
+ function Chip(props) {
127
+ return (_jsxs("button", { type: "button", className: cn('b2b-filterchip', props.active && 'is-on'), onClick: props.onClick, children: [props.icon, _jsx("span", { children: props.label })] }));
128
+ }
129
+ /**
130
+ * The registry loads a route component through a dynamic-import factory and
131
+ * reads its default export (feature 091, FR-013). The named export stays: it is
132
+ * the spelling this module's own code and its tests use.
133
+ */
134
+ export default InventoryPage;
135
+ //# sourceMappingURL=InventoryPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InventoryPage.js","sourceRoot":"","sources":["../../../src/admin/pages/InventoryPage.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * LowStockPage — feature 010 / US4 (T054).
4
+ *
5
+ * Lists every product whose cumulative on-hand has reached or fallen
6
+ * below its `lowStockThreshold`. Mirrors what the Home page Stock
7
+ * Alerts panel surfaces but with no row cap.
8
+ */
9
+ export declare function LowStockPage(): ReactNode;
10
+ /**
11
+ * The registry loads a route component through a dynamic-import factory and
12
+ * reads its default export (feature 091, FR-013). The named export stays: it is
13
+ * the spelling this module's own code and its tests use.
14
+ */
15
+ export default LowStockPage;
16
+ //# sourceMappingURL=LowStockPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LowStockPage.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/LowStockPage.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAiBzE;;;;;;GAMG;AACH,wBAAgB,YAAY,IAAI,SAAS,CAkHxC;AAED;;;;GAIG;AACH,eAAe,YAAY,CAAC"}
@@ -0,0 +1,61 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { Link } from 'react-router-dom';
4
+ import { AlertTriangle } from 'lucide-react';
5
+ import { ApiError, apiClient, useSurfaceVisibility } from '@endora-commerce/admin-kit/lib';
6
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
7
+ /**
8
+ * LowStockPage — feature 010 / US4 (T054).
9
+ *
10
+ * Lists every product whose cumulative on-hand has reached or fallen
11
+ * below its `lowStockThreshold`. Mirrors what the Home page Stock
12
+ * Alerts panel surfaces but with no row cap.
13
+ */
14
+ export function LowStockPage() {
15
+ const t = useTranslation('core');
16
+ // The screen's own gate (2026-08-29) — see `InventoryPage` for the reasoning
17
+ // in full.
18
+ const isVisible = useSurfaceVisibility();
19
+ const canRead = isVisible({ module: 'inventory', requiredPermission: 'inventory:read' });
20
+ const [rows, setRows] = useState([]);
21
+ const [loading, setLoading] = useState(true);
22
+ const [error, setError] = useState(null);
23
+ const refresh = useCallback(async () => {
24
+ if (!canRead) {
25
+ setLoading(false);
26
+ return;
27
+ }
28
+ setLoading(true);
29
+ setError(null);
30
+ try {
31
+ const res = await apiClient.get('/api/v1/admin/inventory/low-stock');
32
+ setRows(res.items);
33
+ }
34
+ catch (err) {
35
+ setError(err instanceof ApiError ? err.envelope.error.message : t('inventory.lowStock.error.load'));
36
+ }
37
+ finally {
38
+ setLoading(false);
39
+ }
40
+ }, [canRead, t]);
41
+ useEffect(() => {
42
+ void refresh();
43
+ }, [refresh]);
44
+ if (!canRead) {
45
+ return _jsx("div", { className: "b2b-page", children: t('inventory.noPermission') });
46
+ }
47
+ return (_jsxs("div", { className: "b2b-page b2b-page--wide", children: [_jsx("div", { className: "b2b-page-head", children: _jsxs("div", { className: "b2b-grow", children: [_jsx("div", { className: "b2b-page-head__title", children: t('inventory.lowStock.title') }), _jsx("div", { className: "b2b-page-head__sub", children: t('inventory.lowStock.description') })] }) }), error ? (_jsx("div", { className: "b2b-card", style: {
48
+ background: 'var(--danger-soft)',
49
+ color: 'var(--danger-soft-fg)',
50
+ padding: 12,
51
+ marginBottom: 16,
52
+ border: '1px solid hsl(8 80% 85%)',
53
+ }, children: error })) : null, _jsx("div", { className: "b2b-card", children: _jsx("div", { className: "b2b-card__body b2b-card__body--flush", children: loading ? (_jsx("div", { style: { padding: 32, color: 'var(--fg-muted)', fontSize: 13 }, children: t('inventory.loading') })) : rows.length === 0 ? (_jsxs("div", { className: "b2b-empty", children: [_jsx("div", { className: "b2b-empty__icon", children: _jsx(AlertTriangle, { size: 20 }) }), _jsx("div", { className: "b2b-empty__title", children: t('inventory.lowStock.empty') }), _jsxs("div", { className: "b2b-empty__sub", children: [t('inventory.lowStock.emptyHintPrefix'), " ", _jsx("code", { className: "b2b-mono", children: "lowStockThreshold" }), " ", t('inventory.lowStock.emptyHintSuffix')] })] })) : (_jsxs("table", { className: "b2b-tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: t('inventory.column.product') }), _jsx("th", { children: t('inventory.column.sku') }), _jsx("th", { className: "num", children: t('inventory.column.cumulativeOnHand') }), _jsx("th", { className: "num", children: t('inventory.column.threshold') }), _jsx("th", {})] }) }), _jsx("tbody", { children: rows.map((r) => (_jsxs("tr", { children: [_jsx("td", { children: r.productName }), _jsx("td", { children: _jsx("span", { className: "b2b-mono", style: { fontSize: 12, color: 'var(--fg-muted)' }, children: r.productSku }) }), _jsx("td", { className: "num b2b-tabular", style: { fontWeight: 600 }, children: r.cumulativeOnHand.toLocaleString() }), _jsx("td", { className: "num b2b-tabular", children: r.lowStockThreshold.toLocaleString() }), _jsx("td", { className: "actions", children: _jsx(Link, { to: `/catalog/products/${r.productId}`, className: "b2b-btn b2b-btn--ghost b2b-btn--sm", children: t('inventory.action.editStock') }) })] }, r.productId))) })] })) }) })] }));
54
+ }
55
+ /**
56
+ * The registry loads a route component through a dynamic-import factory and
57
+ * reads its default export (feature 091, FR-013). The named export stays: it is
58
+ * the spelling this module's own code and its tests use.
59
+ */
60
+ export default LowStockPage;
61
+ //# sourceMappingURL=LowStockPage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LowStockPage.js","sourceRoot":"","sources":["../../../src/admin/pages/LowStockPage.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAkB,MAAM,OAAO,CAAC;AACzE,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC7C,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,gCAAgC,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,iCAAiC,CAAC;AAajE;;;;;;GAMG;AACH,MAAM,UAAU,YAAY;IAC1B,MAAM,CAAC,GAAG,cAAc,CAAC,MAAM,CAAC,CAAC;IACjC,6EAA6E;IAC7E,WAAW;IACX,MAAM,SAAS,GAAG,oBAAoB,EAAE,CAAC;IACzC,MAAM,OAAO,GAAG,SAAS,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,CAAC,CAAC;IACzF,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC,GAAG,QAAQ,CAAgB,EAAE,CAAC,CAAC;IACpD,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IAExD,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAmB,EAAE;QACpD,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,UAAU,CAAC,KAAK,CAAC,CAAC;YAClB,OAAO;QACT,CAAC;QACD,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,SAAS,CAAC,GAAG,CAAmB,mCAAmC,CAAC,CAAC;YACvF,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,QAAQ,CAAC,GAAG,YAAY,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,+BAA+B,CAAC,CAAC,CAAC;QACtG,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,CAAC;IAEjB,SAAS,CAAC,GAAG,EAAE;QACb,KAAK,OAAO,EAAE,CAAC;IACjB,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,cAAK,SAAS,EAAC,UAAU,YAAE,CAAC,CAAC,wBAAwB,CAAC,GAAO,CAAC;IACvE,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,yBAAyB,aACtC,cAAK,SAAS,EAAC,eAAe,YAC5B,eAAK,SAAS,EAAC,UAAU,aACvB,cAAK,SAAS,EAAC,sBAAsB,YAAE,CAAC,CAAC,0BAA0B,CAAC,GAAO,EAC3E,cAAK,SAAS,EAAC,oBAAoB,YAChC,CAAC,CAAC,gCAAgC,CAAC,GAChC,IACF,GACF,EAEL,KAAK,CAAC,CAAC,CAAC,CACP,cACE,SAAS,EAAC,UAAU,EACpB,KAAK,EAAE;oBACL,UAAU,EAAE,oBAAoB;oBAChC,KAAK,EAAE,uBAAuB;oBAC9B,OAAO,EAAE,EAAE;oBACX,YAAY,EAAE,EAAE;oBAChB,MAAM,EAAE,0BAA0B;iBACnC,YAEA,KAAK,GACF,CACP,CAAC,CAAC,CAAC,IAAI,EAER,cAAK,SAAS,EAAC,UAAU,YACvB,cAAK,SAAS,EAAC,sCAAsC,YAClD,OAAO,CAAC,CAAC,CAAC,CACT,cAAK,KAAK,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,EAAE,EAAE,YAAG,CAAC,CAAC,mBAAmB,CAAC,GAAO,CACpG,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,CACtB,eAAK,SAAS,EAAC,WAAW,aACxB,cAAK,SAAS,EAAC,iBAAiB,YAAC,KAAC,aAAa,IAAC,IAAI,EAAE,EAAE,GAAI,GAAM,EAClE,cAAK,SAAS,EAAC,kBAAkB,YAAE,CAAC,CAAC,0BAA0B,CAAC,GAAO,EACvE,eAAK,SAAS,EAAC,gBAAgB,aAC5B,CAAC,CAAC,oCAAoC,CAAC,OAAE,eAAM,SAAS,EAAC,UAAU,kCAAyB,OAAE,CAAC,CAAC,oCAAoC,CAAC,IAClI,IACF,CACP,CAAC,CAAC,CAAC,CACF,iBAAO,SAAS,EAAC,SAAS,aACxB,0BACE,yBACE,uBAAK,CAAC,CAAC,0BAA0B,CAAC,GAAM,EACxC,uBAAK,CAAC,CAAC,sBAAsB,CAAC,GAAM,EACpC,aAAI,SAAS,EAAC,KAAK,YAAE,CAAC,CAAC,mCAAmC,CAAC,GAAM,EACjE,aAAI,SAAS,EAAC,KAAK,YAAE,CAAC,CAAC,4BAA4B,CAAC,GAAM,EAC1D,cAAM,IACH,GACC,EACR,0BACG,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACf,yBACE,uBAAK,CAAC,CAAC,WAAW,GAAM,EACxB,uBACE,eAAM,SAAS,EAAC,UAAU,EAAC,KAAK,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,iBAAiB,EAAE,YACzE,CAAC,CAAC,UAAU,GACR,GACJ,EACL,aAAI,SAAS,EAAC,iBAAiB,EAAC,KAAK,EAAE,EAAE,UAAU,EAAE,GAAG,EAAE,YACvD,CAAC,CAAC,gBAAgB,CAAC,cAAc,EAAE,GACjC,EACL,aAAI,SAAS,EAAC,iBAAiB,YAAE,CAAC,CAAC,iBAAiB,CAAC,cAAc,EAAE,GAAM,EAC3E,aAAI,SAAS,EAAC,SAAS,YACrB,KAAC,IAAI,IACH,EAAE,EAAE,qBAAqB,CAAC,CAAC,SAAS,EAAE,EACtC,SAAS,EAAC,oCAAoC,YAE7C,CAAC,CAAC,4BAA4B,CAAC,GAC3B,GACJ,KAlBE,CAAC,CAAC,SAAS,CAmBf,CACN,CAAC,GACI,IACF,CACT,GACG,GACF,IACF,CACP,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,eAAe,YAAY,CAAC"}
@@ -0,0 +1,17 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * StockImportWizard — feature 010 / US7 (T081).
4
+ *
5
+ * CSV-only for now (XLSX support rides on the same endpoint once the
6
+ * parser dep is wired). Operator picks a warehouse, drops a file, the
7
+ * wizard previews the parsed CSV in dry-run mode, and the operator
8
+ * commits with a second click.
9
+ */
10
+ export declare function StockImportWizard(): ReactNode;
11
+ /**
12
+ * The registry loads a route component through a dynamic-import factory and
13
+ * reads its default export (feature 091, FR-013). The named export stays: it is
14
+ * the spelling this module's own code and its tests use.
15
+ */
16
+ export default StockImportWizard;
17
+ //# sourceMappingURL=StockImportWizard.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StockImportWizard.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/StockImportWizard.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAsD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAyB3F;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,IAAI,SAAS,CA+K7C;AAwED;;;;GAIG;AACH,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,111 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { Link } from 'react-router-dom';
4
+ import { ArrowLeft, Upload } from 'lucide-react';
5
+ import { ApiError, apiClient, useSurfaceVisibility } from '@endora-commerce/admin-kit/lib';
6
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
7
+ import { warehousesClient } from '../api/warehouses-client.js';
8
+ /**
9
+ * StockImportWizard — feature 010 / US7 (T081).
10
+ *
11
+ * CSV-only for now (XLSX support rides on the same endpoint once the
12
+ * parser dep is wired). Operator picks a warehouse, drops a file, the
13
+ * wizard previews the parsed CSV in dry-run mode, and the operator
14
+ * commits with a second click.
15
+ */
16
+ export function StockImportWizard() {
17
+ const t = useTranslation('core');
18
+ /**
19
+ * The screen's own gate (2026-08-29) — see `InventoryPage` for the reasoning
20
+ * in full. This one asks for the **write** code, not the read: the whole
21
+ * screen is a write, and its sidebar entry has always carried a write code
22
+ * (`catalog:write` until this change).
23
+ */
24
+ const isVisible = useSurfaceVisibility();
25
+ const canWrite = isVisible({ module: 'inventory', requiredPermission: 'inventory:write' });
26
+ const [warehouses, setWarehouses] = useState([]);
27
+ const [warehouseId, setWarehouseId] = useState('');
28
+ const [csv, setCsv] = useState('');
29
+ const [filename, setFilename] = useState(null);
30
+ const [preview, setPreview] = useState(null);
31
+ const [committed, setCommitted] = useState(null);
32
+ const [busy, setBusy] = useState(false);
33
+ const [error, setError] = useState(null);
34
+ const refresh = useCallback(async () => {
35
+ if (!canWrite)
36
+ return;
37
+ try {
38
+ const res = await warehousesClient.list({ activeOnly: true, withTotals: false, pageSize: 200 });
39
+ setWarehouses(res.items);
40
+ if (res.items.length > 0 && !warehouseId)
41
+ setWarehouseId(res.items[0].id);
42
+ }
43
+ catch (err) {
44
+ setError(err instanceof ApiError ? err.envelope.error.message : t('inventory.import.error.loadWarehouses'));
45
+ }
46
+ }, [canWrite, warehouseId, t]);
47
+ useEffect(() => {
48
+ void refresh();
49
+ }, [refresh]);
50
+ const handleFile = (e) => {
51
+ const file = e.target.files?.[0];
52
+ if (!file)
53
+ return;
54
+ const reader = new FileReader();
55
+ reader.onload = () => {
56
+ setCsv(String(reader.result ?? ''));
57
+ setFilename(file.name);
58
+ setPreview(null);
59
+ setCommitted(null);
60
+ };
61
+ reader.readAsText(file);
62
+ };
63
+ const send = async (dryRun) => {
64
+ if (!csv || !warehouseId)
65
+ return;
66
+ setBusy(true);
67
+ setError(null);
68
+ try {
69
+ const res = await apiClient.post(`/api/v1/admin/inventory/import?dryRun=${dryRun ? 'true' : 'false'}`, { csv, warehouseId });
70
+ if (dryRun) {
71
+ setPreview(res.data);
72
+ }
73
+ else {
74
+ setCommitted(res.data);
75
+ setPreview(null);
76
+ }
77
+ }
78
+ catch (err) {
79
+ setError(err instanceof ApiError ? err.envelope.error.message : t('inventory.import.error.import'));
80
+ }
81
+ finally {
82
+ setBusy(false);
83
+ }
84
+ };
85
+ const exampleCsv = `sku,onHand\nDEMO-001,42\nDEMO-002,0\n`;
86
+ if (!canWrite) {
87
+ return _jsx("div", { className: "b2b-page", children: t('inventory.noPermission') });
88
+ }
89
+ return (_jsxs("div", { className: "b2b-page", children: [_jsx("div", { className: "b2b-page-head", children: _jsxs("div", { className: "b2b-grow", children: [_jsxs(Link, { to: "/inventory", className: "b2b-btn b2b-btn--ghost b2b-btn--sm", style: { marginBottom: 8, display: 'inline-flex' }, children: [_jsx(ArrowLeft, { size: 13 }), " ", t('inventory.import.back')] }), _jsx("div", { className: "b2b-page-head__title", children: t('inventory.import.title') }), _jsxs("div", { className: "b2b-page-head__sub", children: [t('inventory.import.subPrefix'), " ", _jsx("code", { className: "b2b-mono", children: "sku,onHand" }), t('inventory.import.subSuffix')] })] }) }), error ? (_jsx("div", { className: "b2b-card", style: {
90
+ background: 'var(--danger-soft)',
91
+ color: 'var(--danger-soft-fg)',
92
+ padding: 12,
93
+ marginBottom: 16,
94
+ border: '1px solid hsl(8 80% 85%)',
95
+ }, children: error })) : null, _jsxs("div", { className: "b2b-card", style: { marginBottom: 16 }, children: [_jsx("div", { className: "b2b-card__head", children: _jsx("h2", { children: t('inventory.import.step1') }) }), _jsx("div", { className: "b2b-card__body", children: _jsx("select", { className: "b2b-field", value: warehouseId, onChange: (e) => setWarehouseId(e.target.value), children: warehouses.map((w) => (_jsxs("option", { value: w.id, children: [w.name, " (", w.code, ")"] }, w.id))) }) })] }), _jsxs("div", { className: "b2b-card", style: { marginBottom: 16 }, children: [_jsx("div", { className: "b2b-card__head", children: _jsx("h2", { children: t('inventory.import.step2') }) }), _jsxs("div", { className: "b2b-card__body", children: [_jsx("input", { type: "file", accept: ".csv,text/csv", onChange: handleFile }), filename ? (_jsxs("div", { className: "b2b-help", style: { marginTop: 8 }, children: [t('inventory.import.loadedPrefix'), " ", _jsx("code", { className: "b2b-mono", children: filename }), " ", t('inventory.import.loadedSuffix', { count: csv.split(/\r?\n/).length })] })) : (_jsxs("div", { className: "b2b-help", style: { marginTop: 8 }, children: [t('inventory.import.pasteDirectly'), _jsx("textarea", { className: "b2b-field", rows: 6, style: { marginTop: 8, fontFamily: 'monospace' }, placeholder: exampleCsv, value: csv, onChange: (e) => setCsv(e.target.value) })] }))] })] }), _jsxs("div", { className: "b2b-card", style: { marginBottom: 16 }, children: [_jsx("div", { className: "b2b-card__head", children: _jsx("h2", { children: t('inventory.import.step3') }) }), _jsxs("div", { className: "b2b-card__body", children: [_jsxs("div", { className: "b2b-row", style: { gap: 8 }, children: [_jsxs("button", { type: "button", className: "b2b-btn b2b-btn--default", onClick: () => { void send(true); }, disabled: busy || !csv || !warehouseId, children: [_jsx(Upload, { size: 13 }), " ", t('inventory.import.previewDryRun')] }), _jsx("button", { type: "button", className: "b2b-btn b2b-btn--primary", onClick: () => { void send(false); }, disabled: busy || !csv || !warehouseId || !preview, children: busy ? t('inventory.import.working') : t('inventory.import.commit') })] }), preview ? (_jsx(ResultBlock, { title: t('inventory.import.dryRunSummary'), result: preview, tone: "warn" })) : null, committed ? (_jsx(ResultBlock, { title: t('inventory.import.committed'), result: committed, tone: "success" })) : null] })] })] }));
96
+ }
97
+ function ResultBlock({ title, result, tone, }) {
98
+ const t = useTranslation('core');
99
+ return (_jsxs("div", { className: "b2b-card", style: {
100
+ marginTop: 12,
101
+ padding: 12,
102
+ background: tone === 'success' ? 'var(--success-soft)' : 'var(--surface-muted)',
103
+ }, children: [_jsx("div", { style: { fontSize: 13, fontWeight: 600 }, children: title }), _jsxs("div", { className: "b2b-row", style: { gap: 16, marginTop: 8 }, children: [_jsxs("div", { children: [_jsx("div", { className: "b2b-muted", style: { fontSize: 11 }, children: t('inventory.import.rowsRead') }), _jsx("div", { style: { fontSize: 18, fontWeight: 600 }, children: result.rowsRead })] }), _jsxs("div", { children: [_jsx("div", { className: "b2b-muted", style: { fontSize: 11 }, children: t('inventory.import.applied') }), _jsx("div", { style: { fontSize: 18, fontWeight: 600 }, children: result.rowsApplied })] }), _jsxs("div", { children: [_jsx("div", { className: "b2b-muted", style: { fontSize: 11 }, children: t('inventory.import.skipped') }), _jsx("div", { style: { fontSize: 18, fontWeight: 600 }, children: result.rowsSkipped })] })] }), result.errors.length > 0 ? (_jsxs("div", { style: { marginTop: 12 }, children: [_jsx("div", { className: "b2b-muted", style: { fontSize: 11 }, children: t('inventory.import.errorsCount', { count: result.errors.length }) }), _jsxs("table", { className: "b2b-tbl", style: { marginTop: 4, fontSize: 12 }, children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { style: { width: 60 }, children: t('inventory.import.errors.row') }), _jsx("th", { children: t('inventory.import.errors.sku') }), _jsx("th", { children: t('inventory.import.errors.reason') })] }) }), _jsx("tbody", { children: result.errors.slice(0, 50).map((err, i) => (_jsxs("tr", { children: [_jsx("td", { children: err.row }), _jsx("td", { children: _jsx("span", { className: "b2b-mono", children: err.sku || '—' }) }), _jsx("td", { children: err.reason })] }, `${err.row}-${i}`))) })] }), result.errors.length > 50 ? (_jsx("div", { className: "b2b-help", children: t('inventory.import.errorsTruncated', { total: result.errors.length }) })) : null] })) : null] }));
104
+ }
105
+ /**
106
+ * The registry loads a route component through a dynamic-import factory and
107
+ * reads its default export (feature 091, FR-013). The named export stays: it is
108
+ * the spelling this module's own code and its tests use.
109
+ */
110
+ export default StockImportWizard;
111
+ //# sourceMappingURL=StockImportWizard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"StockImportWizard.js","sourceRoot":"","sources":["../../../src/admin/pages/StockImportWizard.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * WarehouseEditor — create + edit a single warehouse (feature 010 / US1).
4
+ */
5
+ export declare function WarehouseEditor(): ReactNode;
6
+ /**
7
+ * The registry loads a route component through a dynamic-import factory and
8
+ * reads its default export (feature 091, FR-013). The named export stays: it is
9
+ * the spelling this module's own code and its tests use.
10
+ */
11
+ export default WarehouseEditor;
12
+ //# sourceMappingURL=WarehouseEditor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WarehouseEditor.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/WarehouseEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,EAKL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAsFf;;GAEG;AACH,wBAAgB,eAAe,IAAI,SAAS,CAqT3C;AAED;;;;GAIG;AACH,eAAe,eAAe,CAAC"}