@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.
- package/LICENSE +21 -0
- package/README.md +61 -0
- package/dist/admin/api/warehouses-client.d.ts +22 -0
- package/dist/admin/api/warehouses-client.d.ts.map +1 -0
- package/dist/admin/api/warehouses-client.js +32 -0
- package/dist/admin/api/warehouses-client.js.map +1 -0
- package/dist/admin/index.d.ts +43 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +190 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/AvailabilityNotificationsPage.d.ts +15 -0
- package/dist/admin/pages/AvailabilityNotificationsPage.d.ts.map +1 -0
- package/dist/admin/pages/AvailabilityNotificationsPage.js +111 -0
- package/dist/admin/pages/AvailabilityNotificationsPage.js.map +1 -0
- package/dist/admin/pages/InventoryPage.d.ts +17 -0
- package/dist/admin/pages/InventoryPage.d.ts.map +1 -0
- package/dist/admin/pages/InventoryPage.js +135 -0
- package/dist/admin/pages/InventoryPage.js.map +1 -0
- package/dist/admin/pages/LowStockPage.d.ts +16 -0
- package/dist/admin/pages/LowStockPage.d.ts.map +1 -0
- package/dist/admin/pages/LowStockPage.js +61 -0
- package/dist/admin/pages/LowStockPage.js.map +1 -0
- package/dist/admin/pages/StockImportWizard.d.ts +17 -0
- package/dist/admin/pages/StockImportWizard.d.ts.map +1 -0
- package/dist/admin/pages/StockImportWizard.js +111 -0
- package/dist/admin/pages/StockImportWizard.js.map +1 -0
- package/dist/admin/pages/WarehouseEditor.d.ts +12 -0
- package/dist/admin/pages/WarehouseEditor.d.ts.map +1 -0
- package/dist/admin/pages/WarehouseEditor.js +194 -0
- package/dist/admin/pages/WarehouseEditor.js.map +1 -0
- package/dist/admin/pages/WarehousesList.d.ts +12 -0
- package/dist/admin/pages/WarehousesList.d.ts.map +1 -0
- package/dist/admin/pages/WarehousesList.js +69 -0
- package/dist/admin/pages/WarehousesList.js.map +1 -0
- package/dist/admin/zones/ChannelWarehouses.d.ts +49 -0
- package/dist/admin/zones/ChannelWarehouses.d.ts.map +1 -0
- package/dist/admin/zones/ChannelWarehouses.js +109 -0
- package/dist/admin/zones/ChannelWarehouses.js.map +1 -0
- package/dist/backend/demo/reset.d.ts +18 -0
- package/dist/backend/demo/reset.d.ts.map +1 -0
- package/dist/backend/demo/reset.js +20 -0
- package/dist/backend/demo/reset.js.map +1 -0
- package/dist/backend/demo/rows.d.ts +38 -0
- package/dist/backend/demo/rows.d.ts.map +1 -0
- package/dist/backend/demo/rows.js +38 -0
- package/dist/backend/demo/rows.js.map +1 -0
- package/dist/backend/demo/seed.d.ts +26 -0
- package/dist/backend/demo/seed.d.ts.map +1 -0
- package/dist/backend/demo/seed.js +65 -0
- package/dist/backend/demo/seed.js.map +1 -0
- package/dist/backend/email-templates/transactional-defaults.d.ts +11 -0
- package/dist/backend/email-templates/transactional-defaults.d.ts.map +1 -0
- package/dist/backend/email-templates/transactional-defaults.js +49 -0
- package/dist/backend/email-templates/transactional-defaults.js.map +1 -0
- package/dist/backend/entities/availability-notification.entity.d.ts +49 -0
- package/dist/backend/entities/availability-notification.entity.d.ts.map +1 -0
- package/dist/backend/entities/availability-notification.entity.js +93 -0
- package/dist/backend/entities/availability-notification.entity.js.map +1 -0
- package/dist/backend/entities/inventory-threshold.entity.d.ts +24 -0
- package/dist/backend/entities/inventory-threshold.entity.d.ts.map +1 -0
- package/dist/backend/entities/inventory-threshold.entity.js +61 -0
- package/dist/backend/entities/inventory-threshold.entity.js.map +1 -0
- package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.d.ts +15 -0
- package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.d.ts.map +1 -0
- package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.js +51 -0
- package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.js.map +1 -0
- package/dist/backend/entities/stock-allocation.entity.d.ts +22 -0
- package/dist/backend/entities/stock-allocation.entity.d.ts.map +1 -0
- package/dist/backend/entities/stock-allocation.entity.js +69 -0
- package/dist/backend/entities/stock-allocation.entity.js.map +1 -0
- package/dist/backend/entities/stock-level.entity.d.ts +24 -0
- package/dist/backend/entities/stock-level.entity.d.ts.map +1 -0
- package/dist/backend/entities/stock-level.entity.js +74 -0
- package/dist/backend/entities/stock-level.entity.js.map +1 -0
- package/dist/backend/entities/warehouse-channel-assignment.entity.d.ts +17 -0
- package/dist/backend/entities/warehouse-channel-assignment.entity.d.ts.map +1 -0
- package/dist/backend/entities/warehouse-channel-assignment.entity.js +60 -0
- package/dist/backend/entities/warehouse-channel-assignment.entity.js.map +1 -0
- package/dist/backend/entities/warehouse.entity.d.ts +37 -0
- package/dist/backend/entities/warehouse.entity.d.ts.map +1 -0
- package/dist/backend/entities/warehouse.entity.js +90 -0
- package/dist/backend/entities/warehouse.entity.js.map +1 -0
- package/dist/backend/index.d.ts +139 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +351 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/plugin.d.ts +113 -0
- package/dist/backend/plugin.d.ts.map +1 -0
- package/dist/backend/plugin.js +75 -0
- package/dist/backend/plugin.js.map +1 -0
- package/dist/backend/prompt-tools.d.ts +23 -0
- package/dist/backend/prompt-tools.d.ts.map +1 -0
- package/dist/backend/prompt-tools.js +77 -0
- package/dist/backend/prompt-tools.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +62 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +383 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.d.ts +40 -0
- package/dist/backend/routes.d.ts.map +1 -0
- package/dist/backend/routes.js +263 -0
- package/dist/backend/routes.js.map +1 -0
- package/dist/backend/services/audit-references.d.ts +15 -0
- package/dist/backend/services/audit-references.d.ts.map +1 -0
- package/dist/backend/services/audit-references.js +27 -0
- package/dist/backend/services/audit-references.js.map +1 -0
- package/dist/backend/services/availability-notification-service.d.ts +155 -0
- package/dist/backend/services/availability-notification-service.d.ts.map +1 -0
- package/dist/backend/services/availability-notification-service.js +363 -0
- package/dist/backend/services/availability-notification-service.js.map +1 -0
- package/dist/backend/services/availability-worker.d.ts +57 -0
- package/dist/backend/services/availability-worker.d.ts.map +1 -0
- package/dist/backend/services/availability-worker.js +135 -0
- package/dist/backend/services/availability-worker.js.map +1 -0
- package/dist/backend/services/csv-stock-importer.d.ts +52 -0
- package/dist/backend/services/csv-stock-importer.d.ts.map +1 -0
- package/dist/backend/services/csv-stock-importer.js +154 -0
- package/dist/backend/services/csv-stock-importer.js.map +1 -0
- package/dist/backend/services/display-band-resolver.d.ts +19 -0
- package/dist/backend/services/display-band-resolver.d.ts.map +1 -0
- package/dist/backend/services/display-band-resolver.js +21 -0
- package/dist/backend/services/display-band-resolver.js.map +1 -0
- package/dist/backend/services/effective-fulfilment-strategy.d.ts +16 -0
- package/dist/backend/services/effective-fulfilment-strategy.d.ts.map +1 -0
- package/dist/backend/services/effective-fulfilment-strategy.js +16 -0
- package/dist/backend/services/effective-fulfilment-strategy.js.map +1 -0
- package/dist/backend/services/fulfilment-strategy-resolver.d.ts +13 -0
- package/dist/backend/services/fulfilment-strategy-resolver.d.ts.map +1 -0
- package/dist/backend/services/fulfilment-strategy-resolver.js +13 -0
- package/dist/backend/services/fulfilment-strategy-resolver.js.map +1 -0
- package/dist/backend/services/inventory-read-port.d.ts +65 -0
- package/dist/backend/services/inventory-read-port.d.ts.map +1 -0
- package/dist/backend/services/inventory-read-port.js +168 -0
- package/dist/backend/services/inventory-read-port.js.map +1 -0
- package/dist/backend/services/inventory-reservation-apply-port.d.ts +62 -0
- package/dist/backend/services/inventory-reservation-apply-port.d.ts.map +1 -0
- package/dist/backend/services/inventory-reservation-apply-port.js +134 -0
- package/dist/backend/services/inventory-reservation-apply-port.js.map +1 -0
- package/dist/backend/services/low-stock-alert-service.d.ts +87 -0
- package/dist/backend/services/low-stock-alert-service.d.ts.map +1 -0
- package/dist/backend/services/low-stock-alert-service.js +164 -0
- package/dist/backend/services/low-stock-alert-service.js.map +1 -0
- package/dist/backend/services/product-threshold-write.service.d.ts +38 -0
- package/dist/backend/services/product-threshold-write.service.d.ts.map +1 -0
- package/dist/backend/services/product-threshold-write.service.js +80 -0
- package/dist/backend/services/product-threshold-write.service.js.map +1 -0
- package/dist/backend/services/stock-import.service.d.ts +43 -0
- package/dist/backend/services/stock-import.service.d.ts.map +1 -0
- package/dist/backend/services/stock-import.service.js +124 -0
- package/dist/backend/services/stock-import.service.js.map +1 -0
- package/dist/backend/services/stock-level-service.d.ts +146 -0
- package/dist/backend/services/stock-level-service.d.ts.map +1 -0
- package/dist/backend/services/stock-level-service.js +489 -0
- package/dist/backend/services/stock-level-service.js.map +1 -0
- package/dist/backend/services/threshold-admin-service.d.ts +73 -0
- package/dist/backend/services/threshold-admin-service.d.ts.map +1 -0
- package/dist/backend/services/threshold-admin-service.js +167 -0
- package/dist/backend/services/threshold-admin-service.js.map +1 -0
- package/dist/backend/services/threshold-resolver.d.ts +23 -0
- package/dist/backend/services/threshold-resolver.d.ts.map +1 -0
- package/dist/backend/services/threshold-resolver.js +29 -0
- package/dist/backend/services/threshold-resolver.js.map +1 -0
- package/dist/backend/services/threshold-settings-mirror.d.ts +55 -0
- package/dist/backend/services/threshold-settings-mirror.d.ts.map +1 -0
- package/dist/backend/services/threshold-settings-mirror.js +84 -0
- package/dist/backend/services/threshold-settings-mirror.js.map +1 -0
- package/dist/backend/services/warehouse-channel-reconciler.d.ts +19 -0
- package/dist/backend/services/warehouse-channel-reconciler.d.ts.map +1 -0
- package/dist/backend/services/warehouse-channel-reconciler.js +65 -0
- package/dist/backend/services/warehouse-channel-reconciler.js.map +1 -0
- package/dist/backend/services/warehouse-channel-service.d.ts +57 -0
- package/dist/backend/services/warehouse-channel-service.d.ts.map +1 -0
- package/dist/backend/services/warehouse-channel-service.js +205 -0
- package/dist/backend/services/warehouse-channel-service.js.map +1 -0
- package/dist/backend/services/warehouse-country-reference.d.ts +14 -0
- package/dist/backend/services/warehouse-country-reference.d.ts.map +1 -0
- package/dist/backend/services/warehouse-country-reference.js +27 -0
- package/dist/backend/services/warehouse-country-reference.js.map +1 -0
- package/dist/backend/services/warehouse-service.d.ts +86 -0
- package/dist/backend/services/warehouse-service.d.ts.map +1 -0
- package/dist/backend/services/warehouse-service.js +267 -0
- package/dist/backend/services/warehouse-service.js.map +1 -0
- package/dist/manifest.d.ts +219 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +377 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260503T182812_inventory_workflow.d.ts +39 -0
- package/dist/migrations/20260503T182812_inventory_workflow.d.ts.map +1 -0
- package/dist/migrations/20260503T182812_inventory_workflow.js +205 -0
- package/dist/migrations/20260503T182812_inventory_workflow.js.map +1 -0
- package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.d.ts +14 -0
- package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.d.ts.map +1 -0
- package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.js +18 -0
- package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.js.map +1 -0
- package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.d.ts +28 -0
- package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.d.ts.map +1 -0
- package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.js +48 -0
- package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.js.map +1 -0
- package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.d.ts +44 -0
- package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.d.ts.map +1 -0
- package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.js +81 -0
- package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.js.map +1 -0
- package/dist/migrations/20260830T182139_inventory_organization_attribution.d.ts +109 -0
- package/dist/migrations/20260830T182139_inventory_organization_attribution.d.ts.map +1 -0
- package/dist/migrations/20260830T182139_inventory_organization_attribution.js +178 -0
- package/dist/migrations/20260830T182139_inventory_organization_attribution.js.map +1 -0
- package/dist/migrations/20260912T125716_inventory_organization_warehouses.d.ts +34 -0
- package/dist/migrations/20260912T125716_inventory_organization_warehouses.d.ts.map +1 -0
- package/dist/migrations/20260912T125716_inventory_organization_warehouses.js +50 -0
- package/dist/migrations/20260912T125716_inventory_organization_warehouses.js.map +1 -0
- package/dist/migrations/index.d.ts +32 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +39 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/ports/index.d.ts +183 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +2 -0
- package/dist/ports/index.js.map +1 -0
- package/docs/inventory.md +177 -0
- package/i18n/en.json +32 -0
- package/i18n/pl.json +32 -0
- package/package.json +105 -0
- 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":"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"}
|
|
@@ -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"}
|