@nice2dev/ui-erp 1.0.10

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/dist/index.cjs ADDED
@@ -0,0 +1,1271 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const react = require("react");
5
+ const DEFAULT_VIEW_CONFIG$1 = {
6
+ timeUnit: "day",
7
+ showUtilization: true,
8
+ showConflicts: true,
9
+ groupBy: "resource",
10
+ utilizationThreshold: 80
11
+ };
12
+ const TIME_INCREMENTS = {
13
+ hour: 60 * 60 * 1e3,
14
+ day: 24 * 60 * 60 * 1e3,
15
+ week: 7 * 24 * 60 * 60 * 1e3,
16
+ month: 30 * 24 * 60 * 60 * 1e3,
17
+ quarter: 90 * 24 * 60 * 60 * 1e3,
18
+ year: 365 * 24 * 60 * 60 * 1e3
19
+ };
20
+ const NiceResourceAllocation = ({
21
+ resources,
22
+ allocations,
23
+ dateRange,
24
+ viewConfig: externalConfig,
25
+ onAllocationCreate,
26
+ onAllocationUpdate,
27
+ onAllocationDelete,
28
+ onResourceClick,
29
+ readOnly = false,
30
+ className = ""
31
+ }) => {
32
+ var _a, _b;
33
+ const config = { ...DEFAULT_VIEW_CONFIG$1, ...externalConfig };
34
+ const [selectedAllocation, setSelectedAllocation] = react.useState(null);
35
+ const [hoveredCell, setHoveredCell] = react.useState(null);
36
+ const [timeUnit, setTimeUnit] = react.useState(config.timeUnit);
37
+ const [expandedResources, setExpandedResources] = react.useState(
38
+ new Set(resources.map((r) => r.id))
39
+ );
40
+ const [showAllocationModal, setShowAllocationModal] = react.useState(false);
41
+ const [newAllocation, setNewAllocation] = react.useState({});
42
+ const timePeriods = react.useMemo(() => {
43
+ const periods = [];
44
+ const increment = TIME_INCREMENTS[timeUnit];
45
+ let current = new Date(dateRange.start);
46
+ while (current <= dateRange.end) {
47
+ periods.push(new Date(current));
48
+ current = new Date(current.getTime() + increment);
49
+ }
50
+ return periods;
51
+ }, [dateRange.start, dateRange.end, timeUnit]);
52
+ const utilizationMap = react.useMemo(() => {
53
+ const map = /* @__PURE__ */ new Map();
54
+ resources.forEach((resource) => {
55
+ const resourceMap = /* @__PURE__ */ new Map();
56
+ timePeriods.forEach((period) => {
57
+ const periodStart = period.getTime();
58
+ const periodEnd = periodStart + TIME_INCREMENTS[timeUnit];
59
+ const periodAllocations = allocations.filter((a) => {
60
+ if (a.resourceId !== resource.id) {
61
+ return false;
62
+ }
63
+ const allocStart = a.start.getTime();
64
+ const allocEnd = a.end.getTime();
65
+ return allocStart < periodEnd && allocEnd > periodStart;
66
+ });
67
+ const allocatedHours = periodAllocations.reduce((sum, a) => sum + a.hoursPerDay, 0);
68
+ const availableHours = resource.maxCapacity;
69
+ const utilizationPercent = availableHours > 0 ? allocatedHours / availableHours * 100 : 0;
70
+ resourceMap.set(periodStart, {
71
+ resourceId: resource.id,
72
+ period: { start: period, end: new Date(periodEnd) },
73
+ allocatedHours,
74
+ availableHours,
75
+ utilizationPercent,
76
+ overallocated: utilizationPercent > 100
77
+ });
78
+ });
79
+ map.set(resource.id, resourceMap);
80
+ });
81
+ return map;
82
+ }, [resources, allocations, timePeriods, timeUnit]);
83
+ const conflicts = react.useMemo(() => {
84
+ const conflictList = [];
85
+ utilizationMap.forEach((resourceMap, resourceId) => {
86
+ const resource = resources.find((r) => r.id === resourceId);
87
+ resourceMap.forEach((util, periodStart) => {
88
+ if (util.overallocated) {
89
+ const period = new Date(periodStart);
90
+ const periodEnd = periodStart + TIME_INCREMENTS[timeUnit];
91
+ const conflictAllocations = allocations.filter((a) => {
92
+ if (a.resourceId !== resourceId) {
93
+ return false;
94
+ }
95
+ const allocStart = a.start.getTime();
96
+ const allocEnd = a.end.getTime();
97
+ return allocStart < periodEnd && allocEnd > periodStart;
98
+ });
99
+ conflictList.push({
100
+ resourceId,
101
+ date: period,
102
+ allocatedHours: util.allocatedHours,
103
+ maxCapacity: resource.maxCapacity,
104
+ allocations: conflictAllocations
105
+ });
106
+ }
107
+ });
108
+ });
109
+ return conflictList;
110
+ }, [utilizationMap, allocations, resources, timeUnit]);
111
+ const getCellAllocations = react.useCallback(
112
+ (resourceId, date) => {
113
+ const periodStart = date.getTime();
114
+ const periodEnd = periodStart + TIME_INCREMENTS[timeUnit];
115
+ return allocations.filter((a) => {
116
+ if (a.resourceId !== resourceId) {
117
+ return false;
118
+ }
119
+ const allocStart = a.start.getTime();
120
+ const allocEnd = a.end.getTime();
121
+ return allocStart < periodEnd && allocEnd > periodStart;
122
+ });
123
+ },
124
+ [allocations, timeUnit]
125
+ );
126
+ const getCellColor = (resourceId, date) => {
127
+ var _a2;
128
+ const util = (_a2 = utilizationMap.get(resourceId)) == null ? void 0 : _a2.get(date.getTime());
129
+ if (!util) {
130
+ return "transparent";
131
+ }
132
+ if (util.overallocated) {
133
+ return "rgba(239, 68, 68, 0.4)";
134
+ }
135
+ if (util.utilizationPercent >= config.utilizationThreshold) {
136
+ return "rgba(245, 158, 11, 0.3)";
137
+ }
138
+ if (util.utilizationPercent > 0) {
139
+ return "rgba(34, 197, 94, 0.2)";
140
+ }
141
+ return "transparent";
142
+ };
143
+ const formatDate = (date) => {
144
+ switch (timeUnit) {
145
+ case "hour":
146
+ return date.toLocaleTimeString([], { hour: "2-digit" });
147
+ case "day":
148
+ return date.toLocaleDateString([], { weekday: "short", day: "numeric" });
149
+ case "week":
150
+ return `W${Math.ceil(date.getDate() / 7)}`;
151
+ case "month":
152
+ return date.toLocaleDateString([], { month: "short" });
153
+ default:
154
+ return date.toLocaleDateString();
155
+ }
156
+ };
157
+ const handleCellClick = (resourceId, date) => {
158
+ var _a2;
159
+ if (readOnly) {
160
+ return;
161
+ }
162
+ setNewAllocation({
163
+ resourceId,
164
+ start: date,
165
+ end: new Date(date.getTime() + TIME_INCREMENTS[timeUnit]),
166
+ hoursPerDay: ((_a2 = resources.find((r) => r.id === resourceId)) == null ? void 0 : _a2.maxCapacity) || 8,
167
+ status: "tentative"
168
+ });
169
+ setShowAllocationModal(true);
170
+ };
171
+ const handleCreateAllocation = () => {
172
+ if (newAllocation.resourceId && newAllocation.start && newAllocation.end) {
173
+ onAllocationCreate == null ? void 0 : onAllocationCreate({
174
+ resourceId: newAllocation.resourceId,
175
+ start: newAllocation.start,
176
+ end: newAllocation.end,
177
+ hoursPerDay: newAllocation.hoursPerDay || 8,
178
+ status: newAllocation.status || "tentative",
179
+ notes: newAllocation.notes
180
+ });
181
+ setShowAllocationModal(false);
182
+ setNewAllocation({});
183
+ }
184
+ };
185
+ const toggleResource = (resourceId) => {
186
+ setExpandedResources((prev) => {
187
+ const next = new Set(prev);
188
+ if (next.has(resourceId)) {
189
+ next.delete(resourceId);
190
+ } else {
191
+ next.add(resourceId);
192
+ }
193
+ return next;
194
+ });
195
+ };
196
+ const getResourceTypeIcon = (type) => {
197
+ switch (type) {
198
+ case "human":
199
+ return "👤";
200
+ case "equipment":
201
+ return "🔧";
202
+ case "room":
203
+ return "🏢";
204
+ case "vehicle":
205
+ return "🚗";
206
+ case "material":
207
+ return "📦";
208
+ default:
209
+ return "📋";
210
+ }
211
+ };
212
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `nice-resource-allocation ${className}`, children: [
213
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "allocation__toolbar", children: [
214
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "toolbar__left", children: [
215
+ /* @__PURE__ */ jsxRuntime.jsx("h2", { children: "Resource Allocation" }),
216
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "date-range", children: [
217
+ dateRange.start.toLocaleDateString(),
218
+ " - ",
219
+ dateRange.end.toLocaleDateString()
220
+ ] })
221
+ ] }),
222
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "toolbar__center", children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "time-unit-selector", children: ["day", "week", "month"].map((unit) => /* @__PURE__ */ jsxRuntime.jsx(
223
+ "button",
224
+ {
225
+ className: `unit-button ${timeUnit === unit ? "unit-button--active" : ""}`,
226
+ onClick: () => setTimeUnit(unit),
227
+ children: unit.charAt(0).toUpperCase() + unit.slice(1)
228
+ },
229
+ unit
230
+ )) }) }),
231
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "toolbar__right", children: config.showConflicts && conflicts.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "conflicts-badge", children: [
232
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "badge-icon", children: "⚠️" }),
233
+ conflicts.length,
234
+ " Conflict",
235
+ conflicts.length !== 1 ? "s" : ""
236
+ ] }) })
237
+ ] }),
238
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "allocation__legend", children: [
239
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "legend-item", children: [
240
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "legend-color", style: { backgroundColor: "rgba(34, 197, 94, 0.2)" } }),
241
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Allocated" })
242
+ ] }),
243
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "legend-item", children: [
244
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "legend-color", style: { backgroundColor: "rgba(245, 158, 11, 0.3)" } }),
245
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
246
+ "High Utilization (",
247
+ ">",
248
+ "=",
249
+ config.utilizationThreshold,
250
+ "%)"
251
+ ] })
252
+ ] }),
253
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "legend-item", children: [
254
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "legend-color", style: { backgroundColor: "rgba(239, 68, 68, 0.4)" } }),
255
+ /* @__PURE__ */ jsxRuntime.jsx("span", { children: "Overallocated" })
256
+ ] })
257
+ ] }),
258
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "allocation__grid", children: [
259
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid__header", children: [
260
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "resource-header", children: "Resource" }),
261
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "time-headers", children: timePeriods.map((period, idx) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "time-header", children: formatDate(period) }, idx)) })
262
+ ] }),
263
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid__body", children: resources.map((resource) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "resource-row", children: [
264
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "resource-cell", onClick: () => onResourceClick == null ? void 0 : onResourceClick(resource), children: [
265
+ /* @__PURE__ */ jsxRuntime.jsx(
266
+ "button",
267
+ {
268
+ className: "expand-button",
269
+ onClick: (e) => {
270
+ e.stopPropagation();
271
+ toggleResource(resource.id);
272
+ },
273
+ children: expandedResources.has(resource.id) ? "▾" : "▸"
274
+ }
275
+ ),
276
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "resource-icon", children: getResourceTypeIcon(resource.type) }),
277
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "resource-info", children: [
278
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "resource-name", children: resource.name }),
279
+ resource.department && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "resource-dept", children: resource.department })
280
+ ] }),
281
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "resource-capacity", children: [
282
+ resource.maxCapacity,
283
+ "h/day"
284
+ ] })
285
+ ] }),
286
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "time-cells", children: timePeriods.map((period, idx) => {
287
+ var _a2;
288
+ const cellAllocations = getCellAllocations(resource.id, period);
289
+ const util = (_a2 = utilizationMap.get(resource.id)) == null ? void 0 : _a2.get(period.getTime());
290
+ const isHovered = (hoveredCell == null ? void 0 : hoveredCell.resourceId) === resource.id && (hoveredCell == null ? void 0 : hoveredCell.date.getTime()) === period.getTime();
291
+ return /* @__PURE__ */ jsxRuntime.jsxs(
292
+ "div",
293
+ {
294
+ className: `time-cell ${isHovered ? "time-cell--hovered" : ""}`,
295
+ style: { backgroundColor: getCellColor(resource.id, period) },
296
+ onClick: () => handleCellClick(resource.id, period),
297
+ onMouseEnter: () => setHoveredCell({ resourceId: resource.id, date: period }),
298
+ onMouseLeave: () => setHoveredCell(null),
299
+ children: [
300
+ cellAllocations.length > 0 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "allocation-indicators", children: [
301
+ cellAllocations.slice(0, 2).map((alloc) => /* @__PURE__ */ jsxRuntime.jsx(
302
+ "div",
303
+ {
304
+ className: `allocation-dot ${alloc.status}`,
305
+ onClick: (e) => {
306
+ e.stopPropagation();
307
+ setSelectedAllocation(alloc.id);
308
+ }
309
+ },
310
+ alloc.id
311
+ )),
312
+ cellAllocations.length > 2 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "more-indicator", children: [
313
+ "+",
314
+ cellAllocations.length - 2
315
+ ] })
316
+ ] }),
317
+ config.showUtilization && util && util.allocatedHours > 0 && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "utilization-label", children: [
318
+ util.allocatedHours.toFixed(1),
319
+ "h"
320
+ ] })
321
+ ]
322
+ },
323
+ idx
324
+ );
325
+ }) }),
326
+ expandedResources.has(resource.id) && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "expanded-allocations", children: allocations.filter((a) => a.resourceId === resource.id).map((allocation) => {
327
+ const startIdx = timePeriods.findIndex(
328
+ (p) => p.getTime() <= allocation.start.getTime()
329
+ );
330
+ const endIdx = timePeriods.findIndex(
331
+ (p) => p.getTime() >= allocation.end.getTime()
332
+ );
333
+ if (startIdx === -1) {
334
+ return null;
335
+ }
336
+ const span = Math.max(1, endIdx - startIdx);
337
+ const leftPercent = startIdx / timePeriods.length * 100;
338
+ const widthPercent = span / timePeriods.length * 100;
339
+ return /* @__PURE__ */ jsxRuntime.jsxs(
340
+ "div",
341
+ {
342
+ className: `allocation-bar ${allocation.status} ${selectedAllocation === allocation.id ? "selected" : ""}`,
343
+ style: {
344
+ left: `${leftPercent}%`,
345
+ width: `${widthPercent}%`
346
+ },
347
+ onClick: () => setSelectedAllocation(allocation.id),
348
+ children: [
349
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "allocation-label", children: [
350
+ allocation.hoursPerDay,
351
+ "h/day"
352
+ ] }),
353
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
354
+ "button",
355
+ {
356
+ className: "delete-allocation",
357
+ onClick: (e) => {
358
+ e.stopPropagation();
359
+ onAllocationDelete == null ? void 0 : onAllocationDelete(allocation.id);
360
+ },
361
+ children: "×"
362
+ }
363
+ )
364
+ ]
365
+ },
366
+ allocation.id
367
+ );
368
+ }) })
369
+ ] }, resource.id)) })
370
+ ] }),
371
+ showAllocationModal && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "modal-overlay", onClick: () => setShowAllocationModal(false), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "allocation-modal", onClick: (e) => e.stopPropagation(), children: [
372
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { children: "Create Allocation" }),
373
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "modal-form", children: [
374
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
375
+ "Resource",
376
+ /* @__PURE__ */ jsxRuntime.jsxs(
377
+ "select",
378
+ {
379
+ value: newAllocation.resourceId || "",
380
+ onChange: (e) => setNewAllocation((prev) => ({ ...prev, resourceId: e.target.value })),
381
+ children: [
382
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select resource..." }),
383
+ resources.map((r) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: r.id, children: r.name }, r.id))
384
+ ]
385
+ }
386
+ )
387
+ ] }),
388
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
389
+ "Start Date",
390
+ /* @__PURE__ */ jsxRuntime.jsx(
391
+ "input",
392
+ {
393
+ type: "date",
394
+ value: ((_a = newAllocation.start) == null ? void 0 : _a.toISOString().split("T")[0]) || "",
395
+ onChange: (e) => setNewAllocation((prev) => ({ ...prev, start: new Date(e.target.value) }))
396
+ }
397
+ )
398
+ ] }),
399
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
400
+ "End Date",
401
+ /* @__PURE__ */ jsxRuntime.jsx(
402
+ "input",
403
+ {
404
+ type: "date",
405
+ value: ((_b = newAllocation.end) == null ? void 0 : _b.toISOString().split("T")[0]) || "",
406
+ onChange: (e) => setNewAllocation((prev) => ({ ...prev, end: new Date(e.target.value) }))
407
+ }
408
+ )
409
+ ] }),
410
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
411
+ "Hours per Day",
412
+ /* @__PURE__ */ jsxRuntime.jsx(
413
+ "input",
414
+ {
415
+ type: "number",
416
+ min: "0.5",
417
+ max: "24",
418
+ step: "0.5",
419
+ value: newAllocation.hoursPerDay || 8,
420
+ onChange: (e) => setNewAllocation((prev) => ({
421
+ ...prev,
422
+ hoursPerDay: parseFloat(e.target.value)
423
+ }))
424
+ }
425
+ )
426
+ ] }),
427
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
428
+ "Status",
429
+ /* @__PURE__ */ jsxRuntime.jsxs(
430
+ "select",
431
+ {
432
+ value: newAllocation.status || "tentative",
433
+ onChange: (e) => setNewAllocation((prev) => ({
434
+ ...prev,
435
+ status: e.target.value
436
+ })),
437
+ children: [
438
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "tentative", children: "Tentative" }),
439
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "confirmed", children: "Confirmed" })
440
+ ]
441
+ }
442
+ )
443
+ ] }),
444
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
445
+ "Notes",
446
+ /* @__PURE__ */ jsxRuntime.jsx(
447
+ "textarea",
448
+ {
449
+ value: newAllocation.notes || "",
450
+ onChange: (e) => setNewAllocation((prev) => ({ ...prev, notes: e.target.value })),
451
+ placeholder: "Optional notes..."
452
+ }
453
+ )
454
+ ] })
455
+ ] }),
456
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "modal-actions", children: [
457
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "cancel-button", onClick: () => setShowAllocationModal(false), children: "Cancel" }),
458
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "create-button", onClick: handleCreateAllocation, children: "Create Allocation" })
459
+ ] })
460
+ ] }) })
461
+ ] });
462
+ };
463
+ const DEFAULT_VIEW_CONFIG = {
464
+ view: "grid",
465
+ sortBy: "name",
466
+ sortOrder: "asc",
467
+ showImages: true,
468
+ pageSize: 24
469
+ };
470
+ const NiceInventoryManager = ({
471
+ items,
472
+ transactions = [],
473
+ viewConfig: externalConfig,
474
+ onItemCreate,
475
+ onItemUpdate,
476
+ onItemDelete,
477
+ onTransactionCreate,
478
+ onStockCount,
479
+ onItemClick,
480
+ readOnly = false,
481
+ className = ""
482
+ }) => {
483
+ var _a, _b;
484
+ const config = { ...DEFAULT_VIEW_CONFIG, ...externalConfig };
485
+ const [filters, setFilters] = react.useState({});
486
+ const [view, setView] = react.useState(config.view);
487
+ const [sortBy, setSortBy] = react.useState(config.sortBy);
488
+ const [sortOrder, setSortOrder] = react.useState(config.sortOrder);
489
+ const [page, setPage] = react.useState(1);
490
+ const [selectedItems, setSelectedItems] = react.useState(/* @__PURE__ */ new Set());
491
+ const [showItemModal, setShowItemModal] = react.useState(false);
492
+ const [showTransactionModal, setShowTransactionModal] = react.useState(false);
493
+ const [editingItem, setEditingItem] = react.useState(null);
494
+ const [newTransaction, setNewTransaction] = react.useState({});
495
+ const [activeTab, setActiveTab] = react.useState("inventory");
496
+ const categories = react.useMemo(() => {
497
+ return Array.from(new Set(items.map((item) => item.category))).sort();
498
+ }, [items]);
499
+ const filteredItems = react.useMemo(() => {
500
+ var _a2, _b2;
501
+ let result = [...items];
502
+ if (filters.searchQuery) {
503
+ const query = filters.searchQuery.toLowerCase();
504
+ result = result.filter(
505
+ (item) => {
506
+ var _a3;
507
+ return item.name.toLowerCase().includes(query) || item.sku.toLowerCase().includes(query) || ((_a3 = item.description) == null ? void 0 : _a3.toLowerCase().includes(query));
508
+ }
509
+ );
510
+ }
511
+ if ((_a2 = filters.categories) == null ? void 0 : _a2.length) {
512
+ result = result.filter((item) => filters.categories.includes(item.category));
513
+ }
514
+ if ((_b2 = filters.statuses) == null ? void 0 : _b2.length) {
515
+ result = result.filter((item) => filters.statuses.includes(item.status));
516
+ }
517
+ if (filters.lowStockOnly) {
518
+ result = result.filter((item) => item.quantity <= item.reorderLevel);
519
+ }
520
+ result.sort((a, b) => {
521
+ var _a3, _b3;
522
+ let comparison = 0;
523
+ switch (sortBy) {
524
+ case "name":
525
+ comparison = a.name.localeCompare(b.name);
526
+ break;
527
+ case "sku":
528
+ comparison = a.sku.localeCompare(b.sku);
529
+ break;
530
+ case "quantity":
531
+ comparison = a.quantity - b.quantity;
532
+ break;
533
+ case "value":
534
+ comparison = a.quantity * a.cost.amount - b.quantity * b.cost.amount;
535
+ break;
536
+ case "lastUpdated":
537
+ comparison = (((_a3 = a.lastCountDate) == null ? void 0 : _a3.getTime()) || 0) - (((_b3 = b.lastCountDate) == null ? void 0 : _b3.getTime()) || 0);
538
+ break;
539
+ }
540
+ return sortOrder === "asc" ? comparison : -comparison;
541
+ });
542
+ return result;
543
+ }, [items, filters, sortBy, sortOrder]);
544
+ const paginatedItems = react.useMemo(() => {
545
+ const start = (page - 1) * config.pageSize;
546
+ return filteredItems.slice(start, start + config.pageSize);
547
+ }, [filteredItems, page, config.pageSize]);
548
+ const totalPages = Math.ceil(filteredItems.length / config.pageSize);
549
+ const reorderItems = react.useMemo(() => {
550
+ return items.filter((item) => item.quantity <= item.reorderLevel);
551
+ }, [items]);
552
+ const recentTransactions = react.useMemo(() => {
553
+ return [...transactions].sort((a, b) => b.date.getTime() - a.date.getTime()).slice(0, 50);
554
+ }, [transactions]);
555
+ const kanbanGroups = react.useMemo(() => {
556
+ if (view !== "kanban") {
557
+ return null;
558
+ }
559
+ const groups = /* @__PURE__ */ new Map();
560
+ const statuses = [
561
+ "in-stock",
562
+ "low-stock",
563
+ "out-of-stock",
564
+ "on-order",
565
+ "discontinued"
566
+ ];
567
+ statuses.forEach((status) => groups.set(status, []));
568
+ filteredItems.forEach((item) => {
569
+ var _a2;
570
+ (_a2 = groups.get(item.status)) == null ? void 0 : _a2.push(item);
571
+ });
572
+ return groups;
573
+ }, [filteredItems, view]);
574
+ const getStatusColor = (status) => {
575
+ switch (status) {
576
+ case "in-stock":
577
+ return "#22c55e";
578
+ case "low-stock":
579
+ return "#f59e0b";
580
+ case "out-of-stock":
581
+ return "#ef4444";
582
+ case "on-order":
583
+ return "#3b82f6";
584
+ case "discontinued":
585
+ return "#6b7280";
586
+ default:
587
+ return "#6b7280";
588
+ }
589
+ };
590
+ const getTransactionIcon = (type) => {
591
+ switch (type) {
592
+ case "receipt":
593
+ return "📥";
594
+ case "issue":
595
+ return "📤";
596
+ case "transfer":
597
+ return "🔄";
598
+ case "adjustment":
599
+ return "✏️";
600
+ case "return":
601
+ return "↩️";
602
+ case "count":
603
+ return "📊";
604
+ case "write-off":
605
+ return "❌";
606
+ default:
607
+ return "📋";
608
+ }
609
+ };
610
+ const formatCurrency = (amount, symbol = "$") => {
611
+ return `${symbol}${amount.toFixed(2)}`;
612
+ };
613
+ const handleItemSubmit = () => {
614
+ if (!editingItem) {
615
+ return;
616
+ }
617
+ if (editingItem.id) {
618
+ onItemUpdate == null ? void 0 : onItemUpdate(editingItem);
619
+ } else {
620
+ onItemCreate == null ? void 0 : onItemCreate(editingItem);
621
+ }
622
+ setShowItemModal(false);
623
+ setEditingItem(null);
624
+ };
625
+ const handleTransactionSubmit = () => {
626
+ if (newTransaction.itemId && newTransaction.type && newTransaction.quantity) {
627
+ onTransactionCreate == null ? void 0 : onTransactionCreate({
628
+ itemId: newTransaction.itemId,
629
+ type: newTransaction.type,
630
+ quantity: newTransaction.quantity,
631
+ date: /* @__PURE__ */ new Date(),
632
+ reference: newTransaction.reference,
633
+ notes: newTransaction.notes
634
+ });
635
+ setShowTransactionModal(false);
636
+ setNewTransaction({});
637
+ }
638
+ };
639
+ const toggleItemSelection = (itemId) => {
640
+ setSelectedItems((prev) => {
641
+ const next = new Set(prev);
642
+ if (next.has(itemId)) {
643
+ next.delete(itemId);
644
+ } else {
645
+ next.add(itemId);
646
+ }
647
+ return next;
648
+ });
649
+ };
650
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `nice-inventory-manager ${className}`, children: [
651
+ /* @__PURE__ */ jsxRuntime.jsxs("header", { className: "inventory__toolbar", children: [
652
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "toolbar__left", children: [
653
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "search-box", children: [
654
+ /* @__PURE__ */ jsxRuntime.jsx(
655
+ "input",
656
+ {
657
+ type: "text",
658
+ placeholder: "Search items...",
659
+ value: filters.searchQuery || "",
660
+ onChange: (e) => setFilters((prev) => ({ ...prev, searchQuery: e.target.value }))
661
+ }
662
+ ),
663
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "search-icon", children: "🔍" })
664
+ ] }),
665
+ /* @__PURE__ */ jsxRuntime.jsxs(
666
+ "select",
667
+ {
668
+ value: ((_a = filters.categories) == null ? void 0 : _a[0]) || "",
669
+ onChange: (e) => setFilters((prev) => ({
670
+ ...prev,
671
+ categories: e.target.value ? [e.target.value] : void 0
672
+ })),
673
+ children: [
674
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "All Categories" }),
675
+ categories.map((cat) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: cat, children: cat }, cat))
676
+ ]
677
+ }
678
+ ),
679
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { className: "filter-checkbox", children: [
680
+ /* @__PURE__ */ jsxRuntime.jsx(
681
+ "input",
682
+ {
683
+ type: "checkbox",
684
+ checked: filters.lowStockOnly || false,
685
+ onChange: (e) => setFilters((prev) => ({ ...prev, lowStockOnly: e.target.checked }))
686
+ }
687
+ ),
688
+ "Low Stock Only"
689
+ ] })
690
+ ] }),
691
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "toolbar__right", children: [
692
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "view-selector", children: ["grid", "list", "kanban"].map((v) => /* @__PURE__ */ jsxRuntime.jsx(
693
+ "button",
694
+ {
695
+ className: `view-button ${view === v ? "view-button--active" : ""}`,
696
+ onClick: () => setView(v),
697
+ children: v === "grid" ? "⊞" : v === "list" ? "☰" : "▦"
698
+ },
699
+ v
700
+ )) }),
701
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
702
+ "button",
703
+ {
704
+ className: "add-button",
705
+ onClick: () => {
706
+ setEditingItem({
707
+ category: categories[0],
708
+ unit: "pcs",
709
+ quantity: 0,
710
+ reorderLevel: 10,
711
+ reorderQuantity: 100,
712
+ cost: { amount: 0, currency: { code: "USD", symbol: "$", decimalPlaces: 2 } },
713
+ status: "in-stock"
714
+ });
715
+ setShowItemModal(true);
716
+ },
717
+ children: "+ Add Item"
718
+ }
719
+ )
720
+ ] })
721
+ ] }),
722
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inventory__tabs", children: [
723
+ /* @__PURE__ */ jsxRuntime.jsxs(
724
+ "button",
725
+ {
726
+ className: `tab ${activeTab === "inventory" ? "tab--active" : ""}`,
727
+ onClick: () => setActiveTab("inventory"),
728
+ children: [
729
+ "Inventory (",
730
+ items.length,
731
+ ")"
732
+ ]
733
+ }
734
+ ),
735
+ /* @__PURE__ */ jsxRuntime.jsxs(
736
+ "button",
737
+ {
738
+ className: `tab ${activeTab === "transactions" ? "tab--active" : ""}`,
739
+ onClick: () => setActiveTab("transactions"),
740
+ children: [
741
+ "Transactions (",
742
+ transactions.length,
743
+ ")"
744
+ ]
745
+ }
746
+ ),
747
+ /* @__PURE__ */ jsxRuntime.jsxs(
748
+ "button",
749
+ {
750
+ className: `tab ${activeTab === "reorder" ? "tab--active" : ""}`,
751
+ onClick: () => setActiveTab("reorder"),
752
+ children: [
753
+ "Reorder Alerts",
754
+ reorderItems.length > 0 && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "alert-badge", children: reorderItems.length })
755
+ ]
756
+ }
757
+ )
758
+ ] }),
759
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "inventory__content", children: [
760
+ activeTab === "inventory" && /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
761
+ view === "grid" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "items-grid", children: paginatedItems.map((item) => {
762
+ var _a2;
763
+ return /* @__PURE__ */ jsxRuntime.jsxs(
764
+ "div",
765
+ {
766
+ className: `item-card ${selectedItems.has(item.id) ? "item-card--selected" : ""}`,
767
+ onClick: () => onItemClick == null ? void 0 : onItemClick(item),
768
+ children: [
769
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
770
+ "input",
771
+ {
772
+ type: "checkbox",
773
+ className: "item-checkbox",
774
+ checked: selectedItems.has(item.id),
775
+ onChange: () => toggleItemSelection(item.id),
776
+ onClick: (e) => e.stopPropagation()
777
+ }
778
+ ),
779
+ config.showImages && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "item-image", children: ((_a2 = item.images) == null ? void 0 : _a2[0]) ? /* @__PURE__ */ jsxRuntime.jsx("img", { src: item.images[0], alt: item.name }) : /* @__PURE__ */ jsxRuntime.jsx("span", { className: "placeholder-image", children: "📦" }) }),
780
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "item-info", children: [
781
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "item-sku", children: item.sku }),
782
+ /* @__PURE__ */ jsxRuntime.jsx("h4", { className: "item-name", children: item.name }),
783
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "item-category", children: item.category })
784
+ ] }),
785
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "item-stock", children: [
786
+ /* @__PURE__ */ jsxRuntime.jsx(
787
+ "span",
788
+ {
789
+ className: "status-badge",
790
+ style: { backgroundColor: getStatusColor(item.status) },
791
+ children: item.status.replace("-", " ")
792
+ }
793
+ ),
794
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "quantity", children: [
795
+ item.quantity,
796
+ " ",
797
+ item.unit
798
+ ] }),
799
+ item.quantity <= item.reorderLevel && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reorder-alert", children: "⚠️ Low Stock" })
800
+ ] }),
801
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "item-value", children: formatCurrency(item.quantity * item.cost.amount, item.cost.currency.symbol) })
802
+ ]
803
+ },
804
+ item.id
805
+ );
806
+ }) }),
807
+ view === "list" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "items-table", children: /* @__PURE__ */ jsxRuntime.jsxs("table", { children: [
808
+ /* @__PURE__ */ jsxRuntime.jsx("thead", { children: /* @__PURE__ */ jsxRuntime.jsxs("tr", { children: [
809
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx("th", {}),
810
+ /* @__PURE__ */ jsxRuntime.jsxs(
811
+ "th",
812
+ {
813
+ onClick: () => {
814
+ setSortBy("sku");
815
+ setSortOrder((prev) => prev === "asc" ? "desc" : "asc");
816
+ },
817
+ children: [
818
+ "SKU ",
819
+ sortBy === "sku" && (sortOrder === "asc" ? "↑" : "↓")
820
+ ]
821
+ }
822
+ ),
823
+ /* @__PURE__ */ jsxRuntime.jsxs(
824
+ "th",
825
+ {
826
+ onClick: () => {
827
+ setSortBy("name");
828
+ setSortOrder((prev) => prev === "asc" ? "desc" : "asc");
829
+ },
830
+ children: [
831
+ "Name ",
832
+ sortBy === "name" && (sortOrder === "asc" ? "↑" : "↓")
833
+ ]
834
+ }
835
+ ),
836
+ /* @__PURE__ */ jsxRuntime.jsx("th", { children: "Category" }),
837
+ /* @__PURE__ */ jsxRuntime.jsxs(
838
+ "th",
839
+ {
840
+ onClick: () => {
841
+ setSortBy("quantity");
842
+ setSortOrder((prev) => prev === "asc" ? "desc" : "asc");
843
+ },
844
+ children: [
845
+ "Qty ",
846
+ sortBy === "quantity" && (sortOrder === "asc" ? "↑" : "↓")
847
+ ]
848
+ }
849
+ ),
850
+ /* @__PURE__ */ jsxRuntime.jsx("th", { children: "Status" }),
851
+ /* @__PURE__ */ jsxRuntime.jsx("th", { children: "Location" }),
852
+ /* @__PURE__ */ jsxRuntime.jsxs(
853
+ "th",
854
+ {
855
+ onClick: () => {
856
+ setSortBy("value");
857
+ setSortOrder((prev) => prev === "asc" ? "desc" : "asc");
858
+ },
859
+ children: [
860
+ "Value ",
861
+ sortBy === "value" && (sortOrder === "asc" ? "↑" : "↓")
862
+ ]
863
+ }
864
+ ),
865
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx("th", { children: "Actions" })
866
+ ] }) }),
867
+ /* @__PURE__ */ jsxRuntime.jsx("tbody", { children: paginatedItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
868
+ "tr",
869
+ {
870
+ className: selectedItems.has(item.id) ? "row--selected" : "",
871
+ onClick: () => onItemClick == null ? void 0 : onItemClick(item),
872
+ children: [
873
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(
874
+ "input",
875
+ {
876
+ type: "checkbox",
877
+ checked: selectedItems.has(item.id),
878
+ onChange: () => toggleItemSelection(item.id),
879
+ onClick: (e) => e.stopPropagation()
880
+ }
881
+ ) }),
882
+ /* @__PURE__ */ jsxRuntime.jsx("td", { className: "sku-cell", children: item.sku }),
883
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: item.name }),
884
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: item.category }),
885
+ /* @__PURE__ */ jsxRuntime.jsxs("td", { className: item.quantity <= item.reorderLevel ? "low-stock" : "", children: [
886
+ item.quantity,
887
+ " ",
888
+ item.unit
889
+ ] }),
890
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: /* @__PURE__ */ jsxRuntime.jsx(
891
+ "span",
892
+ {
893
+ className: "status-badge",
894
+ style: { backgroundColor: getStatusColor(item.status) },
895
+ children: item.status.replace("-", " ")
896
+ }
897
+ ) }),
898
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: item.location ? `${item.location.warehouseName}${item.location.aisle ? ` / ${item.location.aisle}` : ""}` : "-" }),
899
+ /* @__PURE__ */ jsxRuntime.jsx("td", { children: formatCurrency(
900
+ item.quantity * item.cost.amount,
901
+ item.cost.currency.symbol
902
+ ) }),
903
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsxs("td", { className: "actions-cell", children: [
904
+ /* @__PURE__ */ jsxRuntime.jsx(
905
+ "button",
906
+ {
907
+ className: "action-btn",
908
+ onClick: (e) => {
909
+ e.stopPropagation();
910
+ setEditingItem(item);
911
+ setShowItemModal(true);
912
+ },
913
+ children: "✏️"
914
+ }
915
+ ),
916
+ /* @__PURE__ */ jsxRuntime.jsx(
917
+ "button",
918
+ {
919
+ className: "action-btn",
920
+ onClick: (e) => {
921
+ e.stopPropagation();
922
+ setNewTransaction({ itemId: item.id });
923
+ setShowTransactionModal(true);
924
+ },
925
+ children: "📝"
926
+ }
927
+ ),
928
+ /* @__PURE__ */ jsxRuntime.jsx(
929
+ "button",
930
+ {
931
+ className: "action-btn action-btn--danger",
932
+ onClick: (e) => {
933
+ e.stopPropagation();
934
+ onItemDelete == null ? void 0 : onItemDelete(item.id);
935
+ },
936
+ children: "🗑️"
937
+ }
938
+ )
939
+ ] })
940
+ ]
941
+ },
942
+ item.id
943
+ )) })
944
+ ] }) }),
945
+ view === "kanban" && kanbanGroups && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "items-kanban", children: Array.from(kanbanGroups.entries()).map(([status, statusItems]) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "kanban-column", children: [
946
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "column-header", style: { borderColor: getStatusColor(status) }, children: [
947
+ /* @__PURE__ */ jsxRuntime.jsx(
948
+ "span",
949
+ {
950
+ className: "status-dot",
951
+ style: { backgroundColor: getStatusColor(status) }
952
+ }
953
+ ),
954
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "column-title", children: status.replace("-", " ") }),
955
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "column-count", children: statusItems.length })
956
+ ] }),
957
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "column-items", children: statusItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs(
958
+ "div",
959
+ {
960
+ className: "kanban-card",
961
+ onClick: () => onItemClick == null ? void 0 : onItemClick(item),
962
+ children: [
963
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "card-sku", children: item.sku }),
964
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "card-name", children: item.name }),
965
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "card-qty", children: [
966
+ item.quantity,
967
+ " ",
968
+ item.unit
969
+ ] })
970
+ ]
971
+ },
972
+ item.id
973
+ )) })
974
+ ] }, status)) }),
975
+ totalPages > 1 && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "pagination", children: [
976
+ /* @__PURE__ */ jsxRuntime.jsx("button", { disabled: page === 1, onClick: () => setPage((p) => p - 1), children: "Previous" }),
977
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { children: [
978
+ "Page ",
979
+ page,
980
+ " of ",
981
+ totalPages
982
+ ] }),
983
+ /* @__PURE__ */ jsxRuntime.jsx("button", { disabled: page === totalPages, onClick: () => setPage((p) => p + 1), children: "Next" })
984
+ ] })
985
+ ] }),
986
+ activeTab === "transactions" && /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "transactions-tab", children: [
987
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
988
+ "button",
989
+ {
990
+ className: "add-transaction-button",
991
+ onClick: () => setShowTransactionModal(true),
992
+ children: "+ New Transaction"
993
+ }
994
+ ),
995
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "transactions-list", children: recentTransactions.map((tx) => {
996
+ const item = items.find((i) => i.id === tx.itemId);
997
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "transaction-item", children: [
998
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tx-icon", children: getTransactionIcon(tx.type) }),
999
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "tx-info", children: [
1000
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tx-type", children: tx.type }),
1001
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tx-item", children: (item == null ? void 0 : item.name) || tx.itemId })
1002
+ ] }),
1003
+ /* @__PURE__ */ jsxRuntime.jsxs(
1004
+ "span",
1005
+ {
1006
+ className: `tx-qty ${tx.type === "receipt" || tx.type === "return" ? "positive" : "negative"}`,
1007
+ children: [
1008
+ tx.type === "receipt" || tx.type === "return" ? "+" : "-",
1009
+ tx.quantity
1010
+ ]
1011
+ }
1012
+ ),
1013
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "tx-date", children: tx.date.toLocaleString() }),
1014
+ tx.reference && /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "tx-ref", children: [
1015
+ "Ref: ",
1016
+ tx.reference
1017
+ ] })
1018
+ ] }, tx.id);
1019
+ }) })
1020
+ ] }),
1021
+ activeTab === "reorder" && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reorder-tab", children: reorderItems.length === 0 ? /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "empty-state", children: [
1022
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "empty-icon", children: "✅" }),
1023
+ /* @__PURE__ */ jsxRuntime.jsx("p", { children: "All items are sufficiently stocked" })
1024
+ ] }) : /* @__PURE__ */ jsxRuntime.jsx("div", { className: "reorder-list", children: reorderItems.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reorder-item", children: [
1025
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reorder-info", children: [
1026
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reorder-sku", children: item.sku }),
1027
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "reorder-name", children: item.name })
1028
+ ] }),
1029
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "reorder-stock", children: [
1030
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "current-qty", children: [
1031
+ "Current: ",
1032
+ item.quantity,
1033
+ " ",
1034
+ item.unit
1035
+ ] }),
1036
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "reorder-level", children: [
1037
+ "Reorder at: ",
1038
+ item.reorderLevel
1039
+ ] }),
1040
+ /* @__PURE__ */ jsxRuntime.jsxs("span", { className: "reorder-qty", children: [
1041
+ "Order qty: ",
1042
+ item.reorderQuantity
1043
+ ] })
1044
+ ] }),
1045
+ item.supplier && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "supplier-name", children: item.supplier.name }),
1046
+ !readOnly && /* @__PURE__ */ jsxRuntime.jsx(
1047
+ "button",
1048
+ {
1049
+ className: "create-po-button",
1050
+ onClick: () => console.log("Create PO for", item.id),
1051
+ children: "Create PO"
1052
+ }
1053
+ )
1054
+ ] }, item.id)) }) })
1055
+ ] }),
1056
+ showItemModal && editingItem && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "modal-overlay", onClick: () => setShowItemModal(false), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "item-modal", onClick: (e) => e.stopPropagation(), children: [
1057
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { children: editingItem.id ? "Edit Item" : "Add New Item" }),
1058
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "modal-form", children: [
1059
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "form-row", children: [
1060
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1061
+ "SKU",
1062
+ /* @__PURE__ */ jsxRuntime.jsx(
1063
+ "input",
1064
+ {
1065
+ type: "text",
1066
+ value: editingItem.sku || "",
1067
+ onChange: (e) => setEditingItem((prev) => ({ ...prev, sku: e.target.value }))
1068
+ }
1069
+ )
1070
+ ] }),
1071
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1072
+ "Name",
1073
+ /* @__PURE__ */ jsxRuntime.jsx(
1074
+ "input",
1075
+ {
1076
+ type: "text",
1077
+ value: editingItem.name || "",
1078
+ onChange: (e) => setEditingItem((prev) => ({ ...prev, name: e.target.value }))
1079
+ }
1080
+ )
1081
+ ] })
1082
+ ] }),
1083
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1084
+ "Description",
1085
+ /* @__PURE__ */ jsxRuntime.jsx(
1086
+ "textarea",
1087
+ {
1088
+ value: editingItem.description || "",
1089
+ onChange: (e) => setEditingItem((prev) => ({ ...prev, description: e.target.value }))
1090
+ }
1091
+ )
1092
+ ] }),
1093
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "form-row", children: [
1094
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1095
+ "Category",
1096
+ /* @__PURE__ */ jsxRuntime.jsx(
1097
+ "input",
1098
+ {
1099
+ type: "text",
1100
+ value: editingItem.category || "",
1101
+ onChange: (e) => setEditingItem((prev) => ({ ...prev, category: e.target.value })),
1102
+ list: "categories"
1103
+ }
1104
+ ),
1105
+ /* @__PURE__ */ jsxRuntime.jsx("datalist", { id: "categories", children: categories.map((c) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: c }, c)) })
1106
+ ] }),
1107
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1108
+ "Unit",
1109
+ /* @__PURE__ */ jsxRuntime.jsx(
1110
+ "input",
1111
+ {
1112
+ type: "text",
1113
+ value: editingItem.unit || "",
1114
+ onChange: (e) => setEditingItem((prev) => ({ ...prev, unit: e.target.value }))
1115
+ }
1116
+ )
1117
+ ] })
1118
+ ] }),
1119
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "form-row", children: [
1120
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1121
+ "Quantity",
1122
+ /* @__PURE__ */ jsxRuntime.jsx(
1123
+ "input",
1124
+ {
1125
+ type: "number",
1126
+ value: editingItem.quantity || 0,
1127
+ onChange: (e) => setEditingItem((prev) => ({ ...prev, quantity: parseInt(e.target.value) }))
1128
+ }
1129
+ )
1130
+ ] }),
1131
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1132
+ "Reorder Level",
1133
+ /* @__PURE__ */ jsxRuntime.jsx(
1134
+ "input",
1135
+ {
1136
+ type: "number",
1137
+ value: editingItem.reorderLevel || 0,
1138
+ onChange: (e) => setEditingItem((prev) => ({
1139
+ ...prev,
1140
+ reorderLevel: parseInt(e.target.value)
1141
+ }))
1142
+ }
1143
+ )
1144
+ ] }),
1145
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1146
+ "Reorder Qty",
1147
+ /* @__PURE__ */ jsxRuntime.jsx(
1148
+ "input",
1149
+ {
1150
+ type: "number",
1151
+ value: editingItem.reorderQuantity || 0,
1152
+ onChange: (e) => setEditingItem((prev) => ({
1153
+ ...prev,
1154
+ reorderQuantity: parseInt(e.target.value)
1155
+ }))
1156
+ }
1157
+ )
1158
+ ] })
1159
+ ] }),
1160
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1161
+ "Unit Cost",
1162
+ /* @__PURE__ */ jsxRuntime.jsx(
1163
+ "input",
1164
+ {
1165
+ type: "number",
1166
+ step: "0.01",
1167
+ value: ((_b = editingItem.cost) == null ? void 0 : _b.amount) || 0,
1168
+ onChange: (e) => setEditingItem((prev) => ({
1169
+ ...prev,
1170
+ cost: {
1171
+ ...prev.cost,
1172
+ amount: parseFloat(e.target.value)
1173
+ }
1174
+ }))
1175
+ }
1176
+ )
1177
+ ] })
1178
+ ] }),
1179
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "modal-actions", children: [
1180
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "cancel-button", onClick: () => setShowItemModal(false), children: "Cancel" }),
1181
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "save-button", onClick: handleItemSubmit, children: editingItem.id ? "Save Changes" : "Create Item" })
1182
+ ] })
1183
+ ] }) }),
1184
+ showTransactionModal && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "modal-overlay", onClick: () => setShowTransactionModal(false), children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "transaction-modal", onClick: (e) => e.stopPropagation(), children: [
1185
+ /* @__PURE__ */ jsxRuntime.jsx("h3", { children: "Create Transaction" }),
1186
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "modal-form", children: [
1187
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1188
+ "Item",
1189
+ /* @__PURE__ */ jsxRuntime.jsxs(
1190
+ "select",
1191
+ {
1192
+ value: newTransaction.itemId || "",
1193
+ onChange: (e) => setNewTransaction((prev) => ({ ...prev, itemId: e.target.value })),
1194
+ children: [
1195
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select item..." }),
1196
+ items.map((item) => /* @__PURE__ */ jsxRuntime.jsxs("option", { value: item.id, children: [
1197
+ item.sku,
1198
+ " - ",
1199
+ item.name
1200
+ ] }, item.id))
1201
+ ]
1202
+ }
1203
+ )
1204
+ ] }),
1205
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1206
+ "Type",
1207
+ /* @__PURE__ */ jsxRuntime.jsxs(
1208
+ "select",
1209
+ {
1210
+ value: newTransaction.type || "",
1211
+ onChange: (e) => setNewTransaction((prev) => ({
1212
+ ...prev,
1213
+ type: e.target.value
1214
+ })),
1215
+ children: [
1216
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "", children: "Select type..." }),
1217
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "receipt", children: "Receipt" }),
1218
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "issue", children: "Issue" }),
1219
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "transfer", children: "Transfer" }),
1220
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "adjustment", children: "Adjustment" }),
1221
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "return", children: "Return" }),
1222
+ /* @__PURE__ */ jsxRuntime.jsx("option", { value: "write-off", children: "Write-off" })
1223
+ ]
1224
+ }
1225
+ )
1226
+ ] }),
1227
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1228
+ "Quantity",
1229
+ /* @__PURE__ */ jsxRuntime.jsx(
1230
+ "input",
1231
+ {
1232
+ type: "number",
1233
+ min: "1",
1234
+ value: newTransaction.quantity || "",
1235
+ onChange: (e) => setNewTransaction((prev) => ({ ...prev, quantity: parseInt(e.target.value) }))
1236
+ }
1237
+ )
1238
+ ] }),
1239
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1240
+ "Reference",
1241
+ /* @__PURE__ */ jsxRuntime.jsx(
1242
+ "input",
1243
+ {
1244
+ type: "text",
1245
+ value: newTransaction.reference || "",
1246
+ onChange: (e) => setNewTransaction((prev) => ({ ...prev, reference: e.target.value })),
1247
+ placeholder: "PO number, invoice, etc."
1248
+ }
1249
+ )
1250
+ ] }),
1251
+ /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
1252
+ "Notes",
1253
+ /* @__PURE__ */ jsxRuntime.jsx(
1254
+ "textarea",
1255
+ {
1256
+ value: newTransaction.notes || "",
1257
+ onChange: (e) => setNewTransaction((prev) => ({ ...prev, notes: e.target.value }))
1258
+ }
1259
+ )
1260
+ ] })
1261
+ ] }),
1262
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "modal-actions", children: [
1263
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "cancel-button", onClick: () => setShowTransactionModal(false), children: "Cancel" }),
1264
+ /* @__PURE__ */ jsxRuntime.jsx("button", { className: "save-button", onClick: handleTransactionSubmit, children: "Create Transaction" })
1265
+ ] })
1266
+ ] }) })
1267
+ ] });
1268
+ };
1269
+ exports.NiceInventoryManager = NiceInventoryManager;
1270
+ exports.NiceResourceAllocation = NiceResourceAllocation;
1271
+ //# sourceMappingURL=index.cjs.map