@nice2dev/ui-erp 1.0.11 → 1.0.14

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.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { jsxs, jsx, Fragment } from "react/jsx-runtime";
2
- import { useState, useMemo, useCallback } from "react";
2
+ import React, { useState, useMemo, useCallback, forwardRef, useRef, useEffect } from "react";
3
3
  const DEFAULT_VIEW_CONFIG$1 = {
4
4
  timeUnit: "day",
5
5
  showUtilization: true,
@@ -128,13 +128,13 @@ const NiceResourceAllocation = ({
128
128
  return "transparent";
129
129
  }
130
130
  if (util.overallocated) {
131
- return "rgba(239, 68, 68, 0.4)";
131
+ return "var(--nice-danger-tint-40, rgba(239, 68, 68, 0.4))";
132
132
  }
133
133
  if (util.utilizationPercent >= config.utilizationThreshold) {
134
- return "rgba(245, 158, 11, 0.3)";
134
+ return "var(--nice-warning-tint-30, rgba(245, 158, 11, 0.3))";
135
135
  }
136
136
  if (util.utilizationPercent > 0) {
137
- return "rgba(34, 197, 94, 0.2)";
137
+ return "var(--nice-success-tint-20, rgba(34, 197, 94, 0.2))";
138
138
  }
139
139
  return "transparent";
140
140
  };
@@ -235,11 +235,11 @@ const NiceResourceAllocation = ({
235
235
  ] }),
236
236
  /* @__PURE__ */ jsxs("div", { className: "allocation__legend", children: [
237
237
  /* @__PURE__ */ jsxs("div", { className: "legend-item", children: [
238
- /* @__PURE__ */ jsx("span", { className: "legend-color", style: { backgroundColor: "rgba(34, 197, 94, 0.2)" } }),
238
+ /* @__PURE__ */ jsx("span", { className: "legend-color", style: { backgroundColor: "var(--nice-success-tint-20, rgba(34, 197, 94, 0.2))" } }),
239
239
  /* @__PURE__ */ jsx("span", { children: "Allocated" })
240
240
  ] }),
241
241
  /* @__PURE__ */ jsxs("div", { className: "legend-item", children: [
242
- /* @__PURE__ */ jsx("span", { className: "legend-color", style: { backgroundColor: "rgba(245, 158, 11, 0.3)" } }),
242
+ /* @__PURE__ */ jsx("span", { className: "legend-color", style: { backgroundColor: "var(--nice-warning-tint-30, rgba(245, 158, 11, 0.3))" } }),
243
243
  /* @__PURE__ */ jsxs("span", { children: [
244
244
  "High Utilization (",
245
245
  ">",
@@ -249,7 +249,7 @@ const NiceResourceAllocation = ({
249
249
  ] })
250
250
  ] }),
251
251
  /* @__PURE__ */ jsxs("div", { className: "legend-item", children: [
252
- /* @__PURE__ */ jsx("span", { className: "legend-color", style: { backgroundColor: "rgba(239, 68, 68, 0.4)" } }),
252
+ /* @__PURE__ */ jsx("span", { className: "legend-color", style: { backgroundColor: "var(--nice-danger-tint-40, rgba(239, 68, 68, 0.4))" } }),
253
253
  /* @__PURE__ */ jsx("span", { children: "Overallocated" })
254
254
  ] })
255
255
  ] }),
@@ -572,17 +572,17 @@ const NiceInventoryManager = ({
572
572
  const getStatusColor = (status) => {
573
573
  switch (status) {
574
574
  case "in-stock":
575
- return "#22c55e";
575
+ return "var(--nice-success, #22c55e)";
576
576
  case "low-stock":
577
- return "#f59e0b";
577
+ return "var(--nice-warning, #f59e0b)";
578
578
  case "out-of-stock":
579
- return "#ef4444";
579
+ return "var(--nice-danger, #ef4444)";
580
580
  case "on-order":
581
- return "#3b82f6";
581
+ return "var(--nice-primary, #3b82f6)";
582
582
  case "discontinued":
583
- return "#6b7280";
583
+ return "var(--nice-text-secondary, #6b7280)";
584
584
  default:
585
- return "#6b7280";
585
+ return "var(--nice-text-secondary, #6b7280)";
586
586
  }
587
587
  };
588
588
  const getTransactionIcon = (type) => {
@@ -1264,8 +1264,890 @@ const NiceInventoryManager = ({
1264
1264
  ] }) })
1265
1265
  ] });
1266
1266
  };
1267
+ const STATUS_COLOR = {
1268
+ draft: "var(--nice-color-muted, #6b7280)",
1269
+ issued: "var(--nice-color-info, #2563eb)",
1270
+ sent: "var(--nice-color-info, #2563eb)",
1271
+ paid: "var(--nice-color-success, #16a34a)",
1272
+ "partially-paid": "var(--nice-color-warning, #ca8a04)",
1273
+ overdue: "var(--nice-color-danger, #dc2626)",
1274
+ cancelled: "var(--nice-color-muted, #6b7280)"
1275
+ };
1276
+ function lineNet(line) {
1277
+ const gross = line.quantity * line.unitPrice.amount;
1278
+ const discounted = line.discount ? gross * (1 - line.discount) : gross;
1279
+ return Math.round(discounted);
1280
+ }
1281
+ function lineVat(line) {
1282
+ return Math.round(lineNet(line) * line.vatRate);
1283
+ }
1284
+ function fmtMoney$1(amount, currency, locale) {
1285
+ const code = typeof currency === "string" ? currency : currency.code;
1286
+ const decimals = typeof currency === "string" ? 2 : currency.decimalPlaces ?? 2;
1287
+ return new Intl.NumberFormat(locale, { style: "currency", currency: code }).format(amount / Math.pow(10, decimals));
1288
+ }
1289
+ function fmtDate$1(d, locale) {
1290
+ const dt = d instanceof Date ? d : new Date(d);
1291
+ return new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(dt);
1292
+ }
1293
+ const NiceInvoiceView = forwardRef(
1294
+ function NiceInvoiceView2({ invoice, locale, currency, hideSections, labels, onAction, showActions = false, density = "comfortable", className, style, id }, ref) {
1295
+ var _a;
1296
+ const cur = currency ?? invoice.currency ?? ((_a = invoice.lines[0]) == null ? void 0 : _a.unitPrice.currency) ?? "EUR";
1297
+ const L = {
1298
+ invoiceNumber: "Invoice",
1299
+ issueDate: "Issue date",
1300
+ dueDate: "Due date",
1301
+ seller: "Seller",
1302
+ buyer: "Buyer",
1303
+ description: "Description",
1304
+ qty: "Qty",
1305
+ unitPrice: "Unit price",
1306
+ vat: "VAT",
1307
+ net: "Net",
1308
+ gross: "Gross",
1309
+ subtotal: "Subtotal",
1310
+ vatTotal: "VAT total",
1311
+ total: "Total",
1312
+ vatBreakdown: "VAT breakdown",
1313
+ timeline: "History",
1314
+ notes: "Notes",
1315
+ vatId: "VAT ID",
1316
+ ...labels
1317
+ };
1318
+ const totals = useMemo(() => {
1319
+ let net = 0;
1320
+ let vat = 0;
1321
+ const byRate = /* @__PURE__ */ new Map();
1322
+ for (const ln of invoice.lines) {
1323
+ const n = lineNet(ln);
1324
+ const v = lineVat(ln);
1325
+ net += n;
1326
+ vat += v;
1327
+ const cell = byRate.get(ln.vatRate) ?? { net: 0, vat: 0 };
1328
+ cell.net += n;
1329
+ cell.vat += v;
1330
+ byRate.set(ln.vatRate, cell);
1331
+ }
1332
+ return { net, vat, gross: net + vat, byRate };
1333
+ }, [invoice.lines]);
1334
+ return /* @__PURE__ */ jsxs(
1335
+ "article",
1336
+ {
1337
+ ref,
1338
+ id,
1339
+ className: `nice-invoice-view nice-invoice-view--${density} ${className ?? ""}`,
1340
+ style,
1341
+ "aria-label": `${L.invoiceNumber} ${invoice.invoiceNumber}`,
1342
+ children: [
1343
+ !(hideSections == null ? void 0 : hideSections.header) && /* @__PURE__ */ jsxs("header", { className: "nice-invoice-view__header", children: [
1344
+ /* @__PURE__ */ jsxs("div", { children: [
1345
+ /* @__PURE__ */ jsxs("div", { className: "nice-invoice-view__title", children: [
1346
+ L.invoiceNumber,
1347
+ " ",
1348
+ /* @__PURE__ */ jsx("strong", { children: invoice.invoiceNumber })
1349
+ ] }),
1350
+ /* @__PURE__ */ jsxs("div", { className: "nice-invoice-view__dates", children: [
1351
+ /* @__PURE__ */ jsxs("span", { children: [
1352
+ L.issueDate,
1353
+ ": ",
1354
+ fmtDate$1(invoice.issueDate, locale)
1355
+ ] }),
1356
+ /* @__PURE__ */ jsxs("span", { children: [
1357
+ L.dueDate,
1358
+ ": ",
1359
+ fmtDate$1(invoice.dueDate, locale)
1360
+ ] })
1361
+ ] })
1362
+ ] }),
1363
+ /* @__PURE__ */ jsxs("div", { className: "nice-invoice-view__status", style: { color: STATUS_COLOR[invoice.status] }, children: [
1364
+ /* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "●" }),
1365
+ " ",
1366
+ invoice.status
1367
+ ] }),
1368
+ showActions && /* @__PURE__ */ jsxs("div", { className: "nice-invoice-view__actions", children: [
1369
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onAction == null ? void 0 : onAction("download"), children: "↓" }),
1370
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onAction == null ? void 0 : onAction("print"), children: "⎙" }),
1371
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onAction == null ? void 0 : onAction("send"), children: "✉" })
1372
+ ] })
1373
+ ] }),
1374
+ !(hideSections == null ? void 0 : hideSections.header) && /* @__PURE__ */ jsxs("section", { className: "nice-invoice-view__parties", children: [
1375
+ /* @__PURE__ */ jsxs("div", { children: [
1376
+ /* @__PURE__ */ jsx("h4", { children: L.seller }),
1377
+ /* @__PURE__ */ jsx("div", { children: invoice.seller.name }),
1378
+ invoice.seller.vatId && /* @__PURE__ */ jsxs("div", { children: [
1379
+ L.vatId,
1380
+ ": ",
1381
+ invoice.seller.vatId
1382
+ ] })
1383
+ ] }),
1384
+ /* @__PURE__ */ jsxs("div", { children: [
1385
+ /* @__PURE__ */ jsx("h4", { children: L.buyer }),
1386
+ /* @__PURE__ */ jsx("div", { children: invoice.buyer.name }),
1387
+ invoice.buyer.vatId && /* @__PURE__ */ jsxs("div", { children: [
1388
+ L.vatId,
1389
+ ": ",
1390
+ invoice.buyer.vatId
1391
+ ] })
1392
+ ] })
1393
+ ] }),
1394
+ !(hideSections == null ? void 0 : hideSections.lines) && /* @__PURE__ */ jsxs("table", { className: "nice-invoice-view__lines", children: [
1395
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
1396
+ /* @__PURE__ */ jsx("th", { children: L.description }),
1397
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.qty }),
1398
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.unitPrice }),
1399
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.vat }),
1400
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.net }),
1401
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.gross })
1402
+ ] }) }),
1403
+ /* @__PURE__ */ jsx("tbody", { children: invoice.lines.map((ln) => {
1404
+ const n = lineNet(ln);
1405
+ const v = lineVat(ln);
1406
+ return /* @__PURE__ */ jsxs("tr", { children: [
1407
+ /* @__PURE__ */ jsx("td", { children: ln.description }),
1408
+ /* @__PURE__ */ jsxs("td", { className: "nice-num", children: [
1409
+ ln.quantity,
1410
+ ln.unit ? ` ${ln.unit}` : ""
1411
+ ] }),
1412
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: fmtMoney$1(ln.unitPrice.amount, cur, locale) }),
1413
+ /* @__PURE__ */ jsxs("td", { className: "nice-num", children: [
1414
+ (ln.vatRate * 100).toFixed(0),
1415
+ "%"
1416
+ ] }),
1417
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: fmtMoney$1(n, cur, locale) }),
1418
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: fmtMoney$1(n + v, cur, locale) })
1419
+ ] }, ln.id);
1420
+ }) })
1421
+ ] }),
1422
+ !(hideSections == null ? void 0 : hideSections.vat) && totals.byRate.size > 0 && /* @__PURE__ */ jsxs("section", { className: "nice-invoice-view__vat", children: [
1423
+ /* @__PURE__ */ jsx("h4", { children: L.vatBreakdown }),
1424
+ /* @__PURE__ */ jsxs("table", { children: [
1425
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
1426
+ /* @__PURE__ */ jsx("th", { children: L.vat }),
1427
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.net }),
1428
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.vat }),
1429
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.gross })
1430
+ ] }) }),
1431
+ /* @__PURE__ */ jsx("tbody", { children: [...totals.byRate.entries()].sort((a, b) => b[0] - a[0]).map(([rate, c]) => /* @__PURE__ */ jsxs("tr", { children: [
1432
+ /* @__PURE__ */ jsxs("td", { children: [
1433
+ (rate * 100).toFixed(0),
1434
+ "%"
1435
+ ] }),
1436
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: fmtMoney$1(c.net, cur, locale) }),
1437
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: fmtMoney$1(c.vat, cur, locale) }),
1438
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: fmtMoney$1(c.net + c.vat, cur, locale) })
1439
+ ] }, rate)) })
1440
+ ] })
1441
+ ] }),
1442
+ !(hideSections == null ? void 0 : hideSections.totals) && /* @__PURE__ */ jsxs("section", { className: "nice-invoice-view__totals", "aria-label": L.total, children: [
1443
+ /* @__PURE__ */ jsxs("div", { children: [
1444
+ /* @__PURE__ */ jsx("span", { children: L.subtotal }),
1445
+ /* @__PURE__ */ jsx("span", { children: fmtMoney$1(totals.net, cur, locale) })
1446
+ ] }),
1447
+ /* @__PURE__ */ jsxs("div", { children: [
1448
+ /* @__PURE__ */ jsx("span", { children: L.vatTotal }),
1449
+ /* @__PURE__ */ jsx("span", { children: fmtMoney$1(totals.vat, cur, locale) })
1450
+ ] }),
1451
+ /* @__PURE__ */ jsxs("div", { className: "nice-invoice-view__grand", children: [
1452
+ /* @__PURE__ */ jsx("span", { children: L.total }),
1453
+ /* @__PURE__ */ jsx("strong", { children: fmtMoney$1(totals.gross, cur, locale) })
1454
+ ] })
1455
+ ] }),
1456
+ !(hideSections == null ? void 0 : hideSections.timeline) && invoice.history && invoice.history.length > 0 && /* @__PURE__ */ jsxs("section", { className: "nice-invoice-view__timeline", children: [
1457
+ /* @__PURE__ */ jsx("h4", { children: L.timeline }),
1458
+ /* @__PURE__ */ jsx("ol", { children: invoice.history.map((h, i) => /* @__PURE__ */ jsxs("li", { children: [
1459
+ /* @__PURE__ */ jsx("span", { className: "nice-invoice-view__t-date", children: fmtDate$1(h.at, locale) }),
1460
+ /* @__PURE__ */ jsx("span", { className: "nice-invoice-view__t-status", style: { color: STATUS_COLOR[h.status] }, children: h.status }),
1461
+ h.note && /* @__PURE__ */ jsxs("span", { className: "nice-invoice-view__t-note", children: [
1462
+ " — ",
1463
+ h.note
1464
+ ] })
1465
+ ] }, i)) })
1466
+ ] }),
1467
+ !(hideSections == null ? void 0 : hideSections.notes) && invoice.notes && /* @__PURE__ */ jsxs("section", { className: "nice-invoice-view__notes", children: [
1468
+ /* @__PURE__ */ jsx("h4", { children: L.notes }),
1469
+ /* @__PURE__ */ jsx("p", { children: invoice.notes })
1470
+ ] })
1471
+ ]
1472
+ }
1473
+ );
1474
+ }
1475
+ );
1476
+ function colorFor(occ, colors) {
1477
+ if (occ <= 0.01) {
1478
+ return colors.low;
1479
+ }
1480
+ if (occ < 0.5) {
1481
+ return colors.low;
1482
+ }
1483
+ if (occ < 0.85) {
1484
+ return colors.mid;
1485
+ }
1486
+ return colors.high;
1487
+ }
1488
+ const NiceWarehouseView = forwardRef(
1489
+ function NiceWarehouseView2({
1490
+ warehouseName,
1491
+ cells,
1492
+ colors = { low: "#dcfce7", mid: "#fde68a", high: "#fecaca" },
1493
+ onCellClick,
1494
+ showLegend = true,
1495
+ cellSize = 48,
1496
+ aisleEvery = 4,
1497
+ className,
1498
+ style,
1499
+ id
1500
+ }, ref) {
1501
+ const [hovered, setHovered] = useState(null);
1502
+ const grid = useMemo(() => {
1503
+ const rows = /* @__PURE__ */ new Map();
1504
+ for (const c of cells) {
1505
+ const rowKey = c.row !== void 0 ? `r${c.row}` : c.location.rack ?? c.location.aisle ?? "0";
1506
+ let arr = rows.get(rowKey);
1507
+ if (!arr) {
1508
+ arr = [];
1509
+ rows.set(rowKey, arr);
1510
+ }
1511
+ arr.push(c);
1512
+ }
1513
+ return [...rows.entries()].map(([rowKey, arr]) => ({ rowKey, cells: arr }));
1514
+ }, [cells]);
1515
+ return /* @__PURE__ */ jsxs("div", { ref, id, className: `nice-warehouse-view ${className ?? ""}`, style, children: [
1516
+ /* @__PURE__ */ jsxs("header", { className: "nice-warehouse-view__header", children: [
1517
+ /* @__PURE__ */ jsx("h3", { children: warehouseName }),
1518
+ showLegend && /* @__PURE__ */ jsxs("div", { className: "nice-warehouse-view__legend", "aria-label": "Occupancy legend", children: [
1519
+ /* @__PURE__ */ jsx("span", { style: { background: colors.low } }),
1520
+ " low",
1521
+ /* @__PURE__ */ jsx("span", { style: { background: colors.mid } }),
1522
+ " mid",
1523
+ /* @__PURE__ */ jsx("span", { style: { background: colors.high } }),
1524
+ " high"
1525
+ ] })
1526
+ ] }),
1527
+ /* @__PURE__ */ jsx("div", { className: "nice-warehouse-view__grid", role: "grid", "aria-label": warehouseName, children: grid.map(({ rowKey, cells: row }) => /* @__PURE__ */ jsx("div", { className: "nice-warehouse-view__row", role: "row", children: row.map((c, idx) => {
1528
+ const key = [c.location.rack, c.location.aisle, c.location.shelf, c.location.bin].filter(Boolean).join("-") || String(idx);
1529
+ const aisleBreak = aisleEvery > 0 && idx > 0 && idx % aisleEvery === 0;
1530
+ return /* @__PURE__ */ jsxs(React.Fragment, { children: [
1531
+ aisleBreak && /* @__PURE__ */ jsx("div", { className: "nice-warehouse-view__aisle", "aria-hidden": true }),
1532
+ /* @__PURE__ */ jsx(
1533
+ "button",
1534
+ {
1535
+ type: "button",
1536
+ role: "gridcell",
1537
+ className: "nice-warehouse-view__cell",
1538
+ style: {
1539
+ width: cellSize,
1540
+ height: cellSize,
1541
+ background: colorFor(c.occupancy, colors)
1542
+ },
1543
+ title: `${key} — ${(c.occupancy * 100).toFixed(0)}% (${c.items.length} items)`,
1544
+ onClick: () => onCellClick == null ? void 0 : onCellClick(c),
1545
+ onMouseEnter: () => setHovered(c),
1546
+ onMouseLeave: () => setHovered(null),
1547
+ children: /* @__PURE__ */ jsx("span", { className: "nice-warehouse-view__bin", children: c.location.bin ?? c.location.shelf ?? "" })
1548
+ }
1549
+ )
1550
+ ] }, key);
1551
+ }) }, rowKey)) }),
1552
+ hovered && /* @__PURE__ */ jsxs("aside", { className: "nice-warehouse-view__details", "aria-live": "polite", children: [
1553
+ /* @__PURE__ */ jsxs("strong", { children: [
1554
+ hovered.location.rack,
1555
+ "/",
1556
+ hovered.location.shelf,
1557
+ "/",
1558
+ hovered.location.bin
1559
+ ] }),
1560
+ /* @__PURE__ */ jsxs("div", { children: [
1561
+ hovered.items.length,
1562
+ " items · ",
1563
+ (hovered.occupancy * 100).toFixed(0),
1564
+ "% full"
1565
+ ] }),
1566
+ /* @__PURE__ */ jsxs("ul", { children: [
1567
+ hovered.items.slice(0, 5).map((it) => /* @__PURE__ */ jsxs("li", { children: [
1568
+ it.sku,
1569
+ " — ",
1570
+ it.name
1571
+ ] }, it.id)),
1572
+ hovered.items.length > 5 && /* @__PURE__ */ jsxs("li", { children: [
1573
+ "…+",
1574
+ hovered.items.length - 5
1575
+ ] })
1576
+ ] })
1577
+ ] })
1578
+ ] });
1579
+ }
1580
+ );
1581
+ const STATUS_TINT = {
1582
+ draft: "#6b7280",
1583
+ "pending-approval": "#ca8a04",
1584
+ approved: "#2563eb",
1585
+ ordered: "#0891b2",
1586
+ "partially-received": "#9333ea",
1587
+ received: "#16a34a",
1588
+ cancelled: "#dc2626"
1589
+ };
1590
+ function fmtMoney(amount, currency, locale) {
1591
+ const code = typeof currency === "string" ? currency : currency.code;
1592
+ const decimals = typeof currency === "string" ? 2 : currency.decimalPlaces ?? 2;
1593
+ return new Intl.NumberFormat(locale, { style: "currency", currency: code }).format(
1594
+ amount / Math.pow(10, decimals)
1595
+ );
1596
+ }
1597
+ function fmtDate(d, locale) {
1598
+ if (!d) {
1599
+ return "—";
1600
+ }
1601
+ const dt = d instanceof Date ? d : new Date(d);
1602
+ return new Intl.DateTimeFormat(locale, { dateStyle: "medium" }).format(dt);
1603
+ }
1604
+ const NicePurchaseOrder = forwardRef(
1605
+ function NicePurchaseOrder2({
1606
+ orders,
1607
+ selectable = true,
1608
+ initialSelectedId,
1609
+ locale,
1610
+ labels,
1611
+ readOnly,
1612
+ onOrderApprove,
1613
+ onReceiveItems,
1614
+ onOrderUpdate,
1615
+ className,
1616
+ style,
1617
+ id
1618
+ }, ref) {
1619
+ var _a;
1620
+ const [selectedId, setSelectedId] = useState(
1621
+ initialSelectedId ?? ((_a = orders[0]) == null ? void 0 : _a.id)
1622
+ );
1623
+ const L = {
1624
+ orderNumber: "PO #",
1625
+ supplier: "Supplier",
1626
+ status: "Status",
1627
+ orderDate: "Ordered",
1628
+ expected: "Expected",
1629
+ total: "Total",
1630
+ sku: "SKU",
1631
+ name: "Item",
1632
+ qty: "Qty",
1633
+ received: "Recv",
1634
+ unitPrice: "Unit",
1635
+ lineTotal: "Subtotal",
1636
+ notes: "Notes",
1637
+ approve: "Approve",
1638
+ receive: "Receive all",
1639
+ ...labels
1640
+ };
1641
+ const selected = useMemo(
1642
+ () => orders.find((o) => o.id === selectedId),
1643
+ [orders, selectedId]
1644
+ );
1645
+ return /* @__PURE__ */ jsxs("div", { ref, id, className: `nice-purchase-order ${className ?? ""}`, style, children: [
1646
+ /* @__PURE__ */ jsxs("table", { className: "nice-purchase-order__list", children: [
1647
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
1648
+ /* @__PURE__ */ jsx("th", { children: L.orderNumber }),
1649
+ /* @__PURE__ */ jsx("th", { children: L.supplier }),
1650
+ /* @__PURE__ */ jsx("th", { children: L.status }),
1651
+ /* @__PURE__ */ jsx("th", { children: L.orderDate }),
1652
+ /* @__PURE__ */ jsx("th", { children: L.expected }),
1653
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.total })
1654
+ ] }) }),
1655
+ /* @__PURE__ */ jsx("tbody", { children: orders.map((o) => /* @__PURE__ */ jsxs(
1656
+ "tr",
1657
+ {
1658
+ "aria-selected": o.id === selectedId,
1659
+ className: o.id === selectedId ? "is-selected" : void 0,
1660
+ onClick: () => selectable && setSelectedId(o.id),
1661
+ children: [
1662
+ /* @__PURE__ */ jsx("td", { children: o.orderNumber }),
1663
+ /* @__PURE__ */ jsx("td", { children: o.supplier.name }),
1664
+ /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsxs("span", { style: { color: STATUS_TINT[o.status] }, children: [
1665
+ "● ",
1666
+ o.status
1667
+ ] }) }),
1668
+ /* @__PURE__ */ jsx("td", { children: fmtDate(o.orderDate, locale) }),
1669
+ /* @__PURE__ */ jsx("td", { children: fmtDate(o.expectedDelivery, locale) }),
1670
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: fmtMoney(o.total.amount, o.total.currency, locale) })
1671
+ ]
1672
+ },
1673
+ o.id
1674
+ )) })
1675
+ ] }),
1676
+ selectable && selected && /* @__PURE__ */ jsxs(
1677
+ "section",
1678
+ {
1679
+ className: "nice-purchase-order__detail",
1680
+ "aria-label": `${L.orderNumber} ${selected.orderNumber}`,
1681
+ children: [
1682
+ /* @__PURE__ */ jsxs("header", { children: [
1683
+ /* @__PURE__ */ jsxs("h3", { children: [
1684
+ selected.orderNumber,
1685
+ " — ",
1686
+ selected.supplier.name
1687
+ ] }),
1688
+ !readOnly && /* @__PURE__ */ jsxs("div", { className: "nice-purchase-order__actions", children: [
1689
+ selected.status === "pending-approval" && onOrderApprove && /* @__PURE__ */ jsx("button", { type: "button", onClick: () => onOrderApprove(selected.id), children: L.approve }),
1690
+ (selected.status === "ordered" || selected.status === "partially-received") && onReceiveItems && /* @__PURE__ */ jsx(
1691
+ "button",
1692
+ {
1693
+ type: "button",
1694
+ onClick: () => onReceiveItems(
1695
+ selected.id,
1696
+ selected.items.map((it) => ({
1697
+ itemId: it.itemId,
1698
+ quantity: it.quantity - (it.receivedQuantity ?? 0)
1699
+ }))
1700
+ ),
1701
+ children: L.receive
1702
+ }
1703
+ ),
1704
+ onOrderUpdate && selected.status === "draft" && /* @__PURE__ */ jsx(
1705
+ "button",
1706
+ {
1707
+ type: "button",
1708
+ onClick: () => onOrderUpdate({ ...selected, status: "pending-approval" }),
1709
+ children: "Submit"
1710
+ }
1711
+ )
1712
+ ] })
1713
+ ] }),
1714
+ /* @__PURE__ */ jsxs("table", { className: "nice-purchase-order__items", children: [
1715
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
1716
+ /* @__PURE__ */ jsx("th", { children: L.sku }),
1717
+ /* @__PURE__ */ jsx("th", { children: L.name }),
1718
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.qty }),
1719
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.received }),
1720
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.unitPrice }),
1721
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.lineTotal })
1722
+ ] }) }),
1723
+ /* @__PURE__ */ jsx("tbody", { children: selected.items.map((it) => /* @__PURE__ */ jsxs("tr", { children: [
1724
+ /* @__PURE__ */ jsx("td", { children: it.sku }),
1725
+ /* @__PURE__ */ jsx("td", { children: it.itemName }),
1726
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: it.quantity }),
1727
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: it.receivedQuantity ?? 0 }),
1728
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: fmtMoney(it.unitPrice.amount, it.unitPrice.currency, locale) }),
1729
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: fmtMoney(it.lineTotal.amount, it.lineTotal.currency, locale) })
1730
+ ] }, it.itemId)) }),
1731
+ /* @__PURE__ */ jsx("tfoot", { children: /* @__PURE__ */ jsxs("tr", { children: [
1732
+ /* @__PURE__ */ jsx("td", { colSpan: 5, className: "nice-num", children: L.total }),
1733
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: /* @__PURE__ */ jsx("strong", { children: fmtMoney(selected.total.amount, selected.total.currency, locale) }) })
1734
+ ] }) })
1735
+ ] }),
1736
+ selected.notes && /* @__PURE__ */ jsxs("p", { className: "nice-purchase-order__notes", children: [
1737
+ /* @__PURE__ */ jsxs("strong", { children: [
1738
+ L.notes,
1739
+ ":"
1740
+ ] }),
1741
+ " ",
1742
+ selected.notes
1743
+ ] })
1744
+ ]
1745
+ }
1746
+ )
1747
+ ] });
1748
+ }
1749
+ );
1750
+ const NiceHRDashboard = forwardRef(
1751
+ function NiceHRDashboard2({ employees, labels, hideWidgets, locale, density = "comfortable", onWidgetClick, className, style, id }, ref) {
1752
+ const L = {
1753
+ headcount: "Headcount",
1754
+ fte: "FTE",
1755
+ vacationBalance: "Avg vacation balance",
1756
+ sickLeave: "Avg sick days (YTD)",
1757
+ departments: "Departments",
1758
+ activeEmployees: "Active",
1759
+ ...labels
1760
+ };
1761
+ const stats = useMemo(() => {
1762
+ const active = employees.filter((e) => e.active !== false);
1763
+ const fte = active.reduce((s, e) => s + (e.fte ?? 1), 0);
1764
+ const vacationAvg = active.length === 0 ? 0 : active.reduce((s, e) => s + (e.vacationBalanceDays ?? 0), 0) / active.length;
1765
+ const sickAvg = active.length === 0 ? 0 : active.reduce((s, e) => s + (e.sickLeaveDaysYtd ?? 0), 0) / active.length;
1766
+ const byDepartment = /* @__PURE__ */ new Map();
1767
+ for (const e of active) {
1768
+ const k = e.department ?? "—";
1769
+ byDepartment.set(k, (byDepartment.get(k) ?? 0) + 1);
1770
+ }
1771
+ return { headcount: employees.length, active: active.length, fte, vacationAvg, sickAvg, byDepartment };
1772
+ }, [employees]);
1773
+ const fmt = (n, d = 1) => n.toLocaleString(locale, { maximumFractionDigits: d });
1774
+ const Widget = ({ kind, label, value, hint }) => /* @__PURE__ */ jsxs(
1775
+ "button",
1776
+ {
1777
+ type: "button",
1778
+ className: "nice-hr-dashboard__widget",
1779
+ onClick: () => onWidgetClick == null ? void 0 : onWidgetClick(kind),
1780
+ children: [
1781
+ /* @__PURE__ */ jsx("span", { className: "nice-hr-dashboard__label", children: label }),
1782
+ /* @__PURE__ */ jsx("span", { className: "nice-hr-dashboard__value", children: value }),
1783
+ hint && /* @__PURE__ */ jsx("span", { className: "nice-hr-dashboard__hint", children: hint })
1784
+ ]
1785
+ }
1786
+ );
1787
+ return /* @__PURE__ */ jsxs("div", { ref, id, className: `nice-hr-dashboard nice-hr-dashboard--${density} ${className ?? ""}`, style, role: "group", "aria-label": "HR dashboard", children: [
1788
+ !(hideWidgets == null ? void 0 : hideWidgets.headcount) && /* @__PURE__ */ jsx(Widget, { kind: "headcount", label: L.headcount, value: fmt(stats.headcount, 0), hint: `${L.activeEmployees}: ${fmt(stats.active, 0)}` }),
1789
+ !(hideWidgets == null ? void 0 : hideWidgets.fte) && /* @__PURE__ */ jsx(Widget, { kind: "fte", label: L.fte, value: fmt(stats.fte, 2) }),
1790
+ !(hideWidgets == null ? void 0 : hideWidgets.vacation) && /* @__PURE__ */ jsx(Widget, { kind: "vacation", label: L.vacationBalance, value: `${fmt(stats.vacationAvg, 1)} d` }),
1791
+ !(hideWidgets == null ? void 0 : hideWidgets.sick) && /* @__PURE__ */ jsx(Widget, { kind: "sick", label: L.sickLeave, value: `${fmt(stats.sickAvg, 1)} d` }),
1792
+ !(hideWidgets == null ? void 0 : hideWidgets.departments) && /* @__PURE__ */ jsx(
1793
+ Widget,
1794
+ {
1795
+ kind: "departments",
1796
+ label: L.departments,
1797
+ value: fmt(stats.byDepartment.size, 0),
1798
+ hint: /* @__PURE__ */ jsx("ul", { className: "nice-hr-dashboard__dept-list", children: [...stats.byDepartment.entries()].slice(0, 5).map(([d, n]) => /* @__PURE__ */ jsxs("li", { children: [
1799
+ d,
1800
+ ": ",
1801
+ n
1802
+ ] }, d)) })
1803
+ }
1804
+ )
1805
+ ] });
1806
+ }
1807
+ );
1808
+ const wait = (ms) => new Promise((r) => setTimeout(r, ms));
1809
+ const NICE_VAT_PRESETS = {
1810
+ PL: [
1811
+ { code: "PL-23", rate: 0.23, label: "23%", description: "Stawka podstawowa" },
1812
+ { code: "PL-8", rate: 0.08, label: "8%", description: "Stawka obniżona" },
1813
+ { code: "PL-5", rate: 0.05, label: "5%", description: "Stawka obniżona" },
1814
+ { code: "PL-0", rate: 0, label: "0%", description: "Stawka zerowa (eksport)" },
1815
+ { code: "PL-zw", rate: 0, label: "zw.", description: "Zwolnienie" }
1816
+ ],
1817
+ EU: [
1818
+ { code: "EU-21", rate: 0.21, label: "21%" },
1819
+ { code: "EU-19", rate: 0.19, label: "19%" },
1820
+ { code: "EU-9", rate: 0.09, label: "9%" },
1821
+ { code: "EU-0", rate: 0, label: "0%" }
1822
+ ],
1823
+ UK: [
1824
+ { code: "UK-20", rate: 0.2, label: "20%", description: "Standard" },
1825
+ { code: "UK-5", rate: 0.05, label: "5%", description: "Reduced" },
1826
+ { code: "UK-0", rate: 0, label: "0%", description: "Zero" }
1827
+ ]
1828
+ };
1829
+ const DEFAULT_SEED = {
1830
+ invoices: [],
1831
+ purchaseOrders: [],
1832
+ inventory: [],
1833
+ suppliers: [],
1834
+ employees: [],
1835
+ resources: [],
1836
+ vatRates: NICE_VAT_PRESETS.PL
1837
+ };
1838
+ function useMockErpApi(options = {}) {
1839
+ const { latencyMs = 300, errorRate = 0, seed } = options;
1840
+ const [loading, setLoading] = useState(true);
1841
+ const [error, setError] = useState(null);
1842
+ const [data, setData] = useState(() => ({ ...DEFAULT_SEED, ...seed }));
1843
+ const settledRef = useRef(false);
1844
+ const refresh = useCallback(async () => {
1845
+ setLoading(true);
1846
+ setError(null);
1847
+ await wait(latencyMs);
1848
+ if (Math.random() < errorRate) {
1849
+ setError(new Error("Mock ERP API: simulated failure"));
1850
+ } else {
1851
+ setData((d) => ({ ...d }));
1852
+ }
1853
+ setLoading(false);
1854
+ }, [latencyMs, errorRate]);
1855
+ useEffect(() => {
1856
+ if (settledRef.current) {
1857
+ return;
1858
+ }
1859
+ settledRef.current = true;
1860
+ void refresh();
1861
+ }, [refresh]);
1862
+ const writeWith = useCallback(
1863
+ async (key, item) => {
1864
+ await wait(latencyMs);
1865
+ if (Math.random() < errorRate) {
1866
+ throw new Error("Mock ERP API: write failed");
1867
+ }
1868
+ setData((d) => {
1869
+ const arr = [...d[key]];
1870
+ const idx = arr.findIndex((i) => i.id === item.id);
1871
+ if (idx >= 0) {
1872
+ arr[idx] = item;
1873
+ } else {
1874
+ arr.push(item);
1875
+ }
1876
+ return { ...d, [key]: arr };
1877
+ });
1878
+ },
1879
+ [latencyMs, errorRate]
1880
+ );
1881
+ return useMemo(
1882
+ () => ({
1883
+ loading,
1884
+ error,
1885
+ invoices: data.invoices,
1886
+ purchaseOrders: data.purchaseOrders,
1887
+ inventory: data.inventory,
1888
+ suppliers: data.suppliers,
1889
+ employees: data.employees,
1890
+ resources: data.resources,
1891
+ vatRates: data.vatRates,
1892
+ refresh,
1893
+ upsertInvoice: (i) => writeWith("invoices", i),
1894
+ upsertPurchaseOrder: (p) => writeWith("purchaseOrders", p),
1895
+ upsertInventory: (i) => writeWith("inventory", i)
1896
+ }),
1897
+ [loading, error, data, refresh, writeWith]
1898
+ );
1899
+ }
1900
+ const NiceVatTable = forwardRef(function NiceVatTable2({
1901
+ country = "PL",
1902
+ rates,
1903
+ editable = false,
1904
+ onChange,
1905
+ onRemove,
1906
+ locale,
1907
+ labels,
1908
+ density = "comfortable",
1909
+ className,
1910
+ style,
1911
+ id
1912
+ }, ref) {
1913
+ const [internal, setInternal] = useState(rates ?? NICE_VAT_PRESETS[country]);
1914
+ const L = {
1915
+ code: "Code",
1916
+ rate: "Rate",
1917
+ label: "Label",
1918
+ description: "Description",
1919
+ add: "+ Add",
1920
+ remove: "Remove",
1921
+ ...labels
1922
+ };
1923
+ const update = useCallback(
1924
+ (next) => {
1925
+ setInternal(next);
1926
+ onChange == null ? void 0 : onChange(next);
1927
+ },
1928
+ [onChange]
1929
+ );
1930
+ const onCellEdit = (idx, key, raw) => {
1931
+ const next = [...internal];
1932
+ const r = { ...next[idx] };
1933
+ if (key === "rate") {
1934
+ const n = Number(raw.replace(",", "."));
1935
+ if (!Number.isFinite(n)) {
1936
+ return;
1937
+ }
1938
+ r.rate = n > 1 ? n / 100 : n;
1939
+ } else if (key === "code" || key === "label" || key === "description") {
1940
+ r[key] = raw;
1941
+ }
1942
+ next[idx] = r;
1943
+ update(next);
1944
+ };
1945
+ const addRow = () => {
1946
+ update([...internal, { code: `NEW-${internal.length + 1}`, rate: 0, label: "0%" }]);
1947
+ };
1948
+ const removeRow = (idx) => {
1949
+ const code = internal[idx].code;
1950
+ const next = internal.filter((_, i) => i !== idx);
1951
+ update(next);
1952
+ onRemove == null ? void 0 : onRemove(code);
1953
+ };
1954
+ return /* @__PURE__ */ jsxs(
1955
+ "div",
1956
+ {
1957
+ ref,
1958
+ id,
1959
+ className: `nice-vat-table nice-vat-table--${density} ${className ?? ""}`,
1960
+ style,
1961
+ children: [
1962
+ /* @__PURE__ */ jsxs("table", { children: [
1963
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", { children: [
1964
+ /* @__PURE__ */ jsx("th", { children: L.code }),
1965
+ /* @__PURE__ */ jsx("th", { className: "nice-num", children: L.rate }),
1966
+ /* @__PURE__ */ jsx("th", { children: L.label }),
1967
+ /* @__PURE__ */ jsx("th", { children: L.description }),
1968
+ editable && /* @__PURE__ */ jsx("th", { "aria-label": L.remove })
1969
+ ] }) }),
1970
+ /* @__PURE__ */ jsx("tbody", { children: internal.map((r, idx) => /* @__PURE__ */ jsxs("tr", { children: [
1971
+ /* @__PURE__ */ jsx("td", { children: editable ? /* @__PURE__ */ jsx("input", { value: r.code, onChange: (e) => onCellEdit(idx, "code", e.target.value) }) : r.code }),
1972
+ /* @__PURE__ */ jsx("td", { className: "nice-num", children: editable ? /* @__PURE__ */ jsx(
1973
+ "input",
1974
+ {
1975
+ type: "number",
1976
+ step: "0.01",
1977
+ min: 0,
1978
+ max: 1,
1979
+ value: r.rate,
1980
+ onChange: (e) => onCellEdit(idx, "rate", e.target.value)
1981
+ }
1982
+ ) : `${(r.rate * 100).toLocaleString(locale, { maximumFractionDigits: 2 })}%` }),
1983
+ /* @__PURE__ */ jsx("td", { children: editable ? /* @__PURE__ */ jsx(
1984
+ "input",
1985
+ {
1986
+ value: r.label ?? "",
1987
+ onChange: (e) => onCellEdit(idx, "label", e.target.value)
1988
+ }
1989
+ ) : r.label ?? "" }),
1990
+ /* @__PURE__ */ jsx("td", { children: editable ? /* @__PURE__ */ jsx(
1991
+ "input",
1992
+ {
1993
+ value: r.description ?? "",
1994
+ onChange: (e) => onCellEdit(idx, "description", e.target.value)
1995
+ }
1996
+ ) : r.description ?? "" }),
1997
+ editable && /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx("button", { type: "button", onClick: () => removeRow(idx), "aria-label": L.remove, children: "×" }) })
1998
+ ] }, r.code)) })
1999
+ ] }),
2000
+ editable && /* @__PURE__ */ jsx("button", { type: "button", className: "nice-vat-table__add", onClick: addRow, children: L.add })
2001
+ ]
2002
+ }
2003
+ );
2004
+ });
2005
+ function pad(n) {
2006
+ return n < 10 ? `0${n}` : String(n);
2007
+ }
2008
+ function isoDate(d) {
2009
+ return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())}`;
2010
+ }
2011
+ function escapeXml(s) {
2012
+ return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
2013
+ }
2014
+ function defaultBuildXml(opts) {
2015
+ const { format, period, taxpayer, invoices } = opts;
2016
+ const lines = [];
2017
+ lines.push('<?xml version="1.0" encoding="UTF-8"?>');
2018
+ lines.push(`<JPK xmlns="http://jpk.mf.gov.pl/wzor/2022/01/01/${format}/" formCode="${format}">`);
2019
+ lines.push(" <Naglowek>");
2020
+ lines.push(` <KodFormularza>${format}</KodFormularza>`);
2021
+ lines.push(` <DataOd>${isoDate(period.from)}</DataOd>`);
2022
+ lines.push(` <DataDo>${isoDate(period.to)}</DataDo>`);
2023
+ lines.push(" </Naglowek>");
2024
+ lines.push(" <Podmiot1>");
2025
+ lines.push(` <NIP>${escapeXml(taxpayer.nip)}</NIP>`);
2026
+ lines.push(` <PelnaNazwa>${escapeXml(taxpayer.name)}</PelnaNazwa>`);
2027
+ if (taxpayer.regon) {
2028
+ lines.push(` <REGON>${escapeXml(taxpayer.regon)}</REGON>`);
2029
+ }
2030
+ lines.push(" </Podmiot1>");
2031
+ for (const inv of invoices) {
2032
+ lines.push(" <Faktura>");
2033
+ lines.push(` <NumerFaktury>${escapeXml(inv.invoiceNumber)}</NumerFaktury>`);
2034
+ lines.push(
2035
+ ` <DataWystawienia>${isoDate(inv.issueDate instanceof Date ? inv.issueDate : new Date(inv.issueDate))}</DataWystawienia>`
2036
+ );
2037
+ lines.push(` <NazwaNabywcy>${escapeXml(inv.buyer.name)}</NazwaNabywcy>`);
2038
+ if (inv.buyer.vatId) {
2039
+ lines.push(` <NIPNabywcy>${escapeXml(inv.buyer.vatId)}</NIPNabywcy>`);
2040
+ }
2041
+ let net = 0;
2042
+ let vat = 0;
2043
+ for (const ln of inv.lines) {
2044
+ const n = Math.round(ln.quantity * ln.unitPrice.amount * (1 - (ln.discount ?? 0)));
2045
+ const v = Math.round(n * ln.vatRate);
2046
+ net += n;
2047
+ vat += v;
2048
+ }
2049
+ lines.push(` <SumaNetto>${(net / 100).toFixed(2)}</SumaNetto>`);
2050
+ lines.push(` <SumaVAT>${(vat / 100).toFixed(2)}</SumaVAT>`);
2051
+ lines.push(` <SumaBrutto>${((net + vat) / 100).toFixed(2)}</SumaBrutto>`);
2052
+ lines.push(" </Faktura>");
2053
+ }
2054
+ lines.push("</JPK>");
2055
+ return lines.join("\n");
2056
+ }
2057
+ const NiceJpkExporter = forwardRef(
2058
+ function NiceJpkExporter2({
2059
+ invoices,
2060
+ taxpayer,
2061
+ defaultFormat = "JPK_V7M",
2062
+ defaultPeriod,
2063
+ buildXml = defaultBuildXml,
2064
+ onExport,
2065
+ filenameFor,
2066
+ labels,
2067
+ className,
2068
+ style,
2069
+ id
2070
+ }, ref) {
2071
+ const today = /* @__PURE__ */ new Date();
2072
+ const [format, setFormat] = useState(defaultFormat);
2073
+ const [from, setFrom] = useState(
2074
+ isoDate((defaultPeriod == null ? void 0 : defaultPeriod.from) ?? new Date(today.getFullYear(), today.getMonth(), 1))
2075
+ );
2076
+ const [to, setTo] = useState(
2077
+ isoDate((defaultPeriod == null ? void 0 : defaultPeriod.to) ?? new Date(today.getFullYear(), today.getMonth() + 1, 0))
2078
+ );
2079
+ const L = {
2080
+ format: "Format",
2081
+ from: "From",
2082
+ to: "To",
2083
+ export: "Export",
2084
+ ...labels
2085
+ };
2086
+ const exportNow = useCallback(() => {
2087
+ const opts = {
2088
+ format,
2089
+ period: { from: new Date(from), to: new Date(to) },
2090
+ taxpayer,
2091
+ invoices
2092
+ };
2093
+ const xml = buildXml(opts);
2094
+ const blob = new Blob([xml], { type: "application/xml" });
2095
+ const filename = (filenameFor == null ? void 0 : filenameFor(opts)) ?? `${format}_${from}_${to}.xml`;
2096
+ onExport == null ? void 0 : onExport(xml, blob, opts);
2097
+ if (typeof window !== "undefined" && typeof URL.createObjectURL === "function") {
2098
+ const url = URL.createObjectURL(blob);
2099
+ const a = document.createElement("a");
2100
+ a.href = url;
2101
+ a.download = filename;
2102
+ document.body.appendChild(a);
2103
+ a.click();
2104
+ a.remove();
2105
+ URL.revokeObjectURL(url);
2106
+ }
2107
+ }, [format, from, to, taxpayer, invoices, buildXml, onExport, filenameFor]);
2108
+ return /* @__PURE__ */ jsxs("div", { ref, id, className: `nice-jpk-exporter ${className ?? ""}`, style, children: [
2109
+ /* @__PURE__ */ jsxs("label", { children: [
2110
+ L.format,
2111
+ /* @__PURE__ */ jsxs(
2112
+ "select",
2113
+ {
2114
+ value: format,
2115
+ onChange: (e) => setFormat(e.target.value),
2116
+ children: [
2117
+ /* @__PURE__ */ jsx("option", { value: "JPK_V7M", children: "JPK_V7M" }),
2118
+ /* @__PURE__ */ jsx("option", { value: "JPK_V7K", children: "JPK_V7K" }),
2119
+ /* @__PURE__ */ jsx("option", { value: "JPK_FA", children: "JPK_FA" })
2120
+ ]
2121
+ }
2122
+ )
2123
+ ] }),
2124
+ /* @__PURE__ */ jsxs("label", { children: [
2125
+ L.from,
2126
+ /* @__PURE__ */ jsx("input", { type: "date", value: from, onChange: (e) => setFrom(e.target.value) })
2127
+ ] }),
2128
+ /* @__PURE__ */ jsxs("label", { children: [
2129
+ L.to,
2130
+ /* @__PURE__ */ jsx("input", { type: "date", value: to, onChange: (e) => setTo(e.target.value) })
2131
+ ] }),
2132
+ /* @__PURE__ */ jsx("button", { type: "button", onClick: exportNow, children: L.export }),
2133
+ /* @__PURE__ */ jsxs("small", { children: [
2134
+ invoices.length,
2135
+ " invoices ready"
2136
+ ] })
2137
+ ] });
2138
+ }
2139
+ );
1267
2140
  export {
2141
+ NICE_VAT_PRESETS,
2142
+ NiceHRDashboard,
1268
2143
  NiceInventoryManager,
1269
- NiceResourceAllocation
2144
+ NiceInvoiceView,
2145
+ NiceJpkExporter,
2146
+ NicePurchaseOrder,
2147
+ NiceResourceAllocation,
2148
+ NiceVatTable,
2149
+ NiceWarehouseView,
2150
+ defaultBuildXml as buildJpkXml,
2151
+ useMockErpApi
1270
2152
  };
1271
2153
  //# sourceMappingURL=index.mjs.map