mgv-backoffice 1.4.0 → 1.8.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/dist/ui-lib.js CHANGED
@@ -772,28 +772,29 @@ var qe = /* @__PURE__ */ W(We, [["render", Ke]]), G = /* @__PURE__ */ function(e
772
772
  }
773
773
  return (e, t) => (_(), a("div", Qe, [o("div", { class: f(["border border-gray-300 relative aspect-square rounded-lg bg-white shadow-sm overflow-hidden flex items-center justify-center text-center", i()]) }, [b(e.$slots, "default"), o("div", { class: f(["absolute bottom-0 left-0 h-1 w-full", r.value]) }, null, 2)], 2)]));
774
774
  }
775
- }), et = { class: "relative rounded-xl border-2 border-dashed border-orange-300 bg-white p-6" }, tt = {
775
+ }), et = { class: "relative rounded-xl border-2 border-dashed border-orange-300 bg-white p-6 dark:border-orange-700 dark:bg-slate-800" }, tt = {
776
776
  key: 0,
777
- class: "absolute right-4 top-4 rounded-md bg-orange-100 px-3 py-1 text-xs font-bold tracking-wide text-orange-500"
778
- }, nt = { class: "flex items-start justify-between" }, rt = { class: "text-sm font-bold tracking-wide text-gray-800" }, it = { class: "mt-1 text-4xl font-bold text-gray-400" }, at = { class: "mt-1 text-sm font-medium text-orange-400" }, ot = /* @__PURE__ */ l({
777
+ class: "absolute right-4 top-4 rounded-md bg-orange-100 px-3 py-1 text-xs font-bold tracking-wide text-orange-500 dark:bg-orange-900/40 dark:text-orange-400"
778
+ }, nt = { class: "flex items-start justify-between" }, rt = { class: "text-sm font-bold tracking-wide text-gray-800 dark:text-slate-200" }, it = { class: "mt-1 text-4xl font-bold text-gray-400 dark:text-slate-300" }, at = { class: "mt-1 text-sm font-medium text-orange-400 dark:text-orange-400" }, ot = /* @__PURE__ */ l({
779
779
  __name: "EarningsCard",
780
780
  props: {
781
781
  title: { default: "TOTAL EARNINGS" },
782
782
  amount: { default: 0 },
783
783
  subtitle: { default: "Lifetime commission" },
784
784
  badge: { default: "" },
785
- currency: { default: "$" }
785
+ currency: { default: "$" },
786
+ decimals: { default: 2 }
786
787
  },
787
788
  setup(e) {
788
789
  let t = e, r = n(() => t.currency + t.amount.toLocaleString("en-US", {
789
- minimumFractionDigits: 2,
790
- maximumFractionDigits: 2
790
+ minimumFractionDigits: t.decimals,
791
+ maximumFractionDigits: t.decimals
791
792
  }));
792
793
  return (t, n) => (_(), a("div", et, [e.badge ? (_(), a("div", tt, C(e.badge), 1)) : i("", !0), o("div", nt, [o("div", null, [
793
794
  o("p", rt, C(e.title), 1),
794
795
  o("p", it, C(r.value), 1),
795
796
  o("p", at, C(e.subtitle), 1)
796
- ]), n[0] ||= o("div", { class: "mt-6 flex h-12 w-12 items-center justify-center rounded-xl bg-orange-50" }, [o("svg", {
797
+ ]), n[0] ||= o("div", { class: "mt-6 flex h-12 w-12 items-center justify-center rounded-xl bg-orange-50 dark:bg-orange-900/30" }, [o("svg", {
797
798
  class: "h-6 w-6 text-orange-400",
798
799
  viewBox: "0 0 24 24",
799
800
  fill: "none",
@@ -1558,10 +1559,210 @@ var Vt = ["aria-label", "aria-expanded"], Ht = { class: "flex flex-col h-full" }
1558
1559
  }, [b(t.$slots, "default")], 10, dn)
1559
1560
  ], 2));
1560
1561
  }
1562
+ }), pn = { class: "flex items-center justify-between mb-8" }, mn = { class: "flex items-center gap-3" }, hn = { class: "flex items-center gap-2" }, gn = /* @__PURE__ */ l({
1563
+ __name: "BasePageHeader",
1564
+ props: {
1565
+ title: {},
1566
+ subtitle: { default: "" },
1567
+ iconColor: { default: "emerald" },
1568
+ maxWidthClass: { default: "max-w-4xl" }
1569
+ },
1570
+ setup(e) {
1571
+ let t = e, { isDark: r } = Y(), s = X(), c = n(() => {
1572
+ let e = {
1573
+ emerald: {
1574
+ dark: "bg-emerald-500/10",
1575
+ light: "bg-emerald-50"
1576
+ },
1577
+ sky: {
1578
+ dark: "bg-sky-500/10",
1579
+ light: "bg-sky-50"
1580
+ },
1581
+ red: {
1582
+ dark: "bg-red-500/10",
1583
+ light: "bg-red-50"
1584
+ },
1585
+ amber: {
1586
+ dark: "bg-amber-500/10",
1587
+ light: "bg-amber-50"
1588
+ }
1589
+ }[t.iconColor];
1590
+ return r.value ? e.dark : e.light;
1591
+ }), l = n(() => {
1592
+ let e = {
1593
+ emerald: {
1594
+ dark: "text-emerald-400",
1595
+ light: "text-emerald-600"
1596
+ },
1597
+ sky: {
1598
+ dark: "text-sky-400",
1599
+ light: "text-sky-600"
1600
+ },
1601
+ red: {
1602
+ dark: "text-red-400",
1603
+ light: "text-red-500"
1604
+ },
1605
+ amber: {
1606
+ dark: "text-amber-400",
1607
+ light: "text-amber-600"
1608
+ }
1609
+ }[t.iconColor];
1610
+ return r.value ? e.dark : e.light;
1611
+ });
1612
+ return (t, n) => (_(), a("div", { class: f(["mx-auto px-4 sm:px-6", e.maxWidthClass]) }, [o("div", pn, [o("div", mn, [o("div", { class: f(["w-10 h-10 rounded-lg flex items-center justify-center", c.value]) }, [b(t.$slots, "icon", { iconClass: l.value })], 2), o("div", null, [o("h1", { class: f(["text-2xl font-bold", w(s).primaryTextSoft]) }, C(e.title), 3), e.subtitle ? (_(), a("p", {
1613
+ key: 0,
1614
+ class: f(["text-sm", w(s).dimTextAlt])
1615
+ }, C(e.subtitle), 3)) : i("", !0)])]), o("div", hn, [b(t.$slots, "actions")])])], 2));
1616
+ }
1617
+ }), _n = [
1618
+ "type",
1619
+ "disabled",
1620
+ "title"
1621
+ ], vn = { key: 0 }, yn = /* @__PURE__ */ l({
1622
+ __name: "BaseToolbarButton",
1623
+ props: {
1624
+ label: { default: "" },
1625
+ variant: { default: "neutral" },
1626
+ disabled: {
1627
+ type: Boolean,
1628
+ default: !1
1629
+ },
1630
+ title: { default: void 0 },
1631
+ type: { default: "button" }
1632
+ },
1633
+ emits: ["click"],
1634
+ setup(e) {
1635
+ let t = e, { isDark: r } = Y(), o = n(() => {
1636
+ let e = {
1637
+ neutral: {
1638
+ dark: "bg-gray-800 text-gray-100 border-gray-700 hover:bg-gray-700",
1639
+ light: "bg-white text-gray-700 border-gray-200 hover:bg-gray-100"
1640
+ },
1641
+ danger: {
1642
+ dark: "bg-red-600 text-white border-red-600 hover:bg-red-500",
1643
+ light: "bg-red-600 text-white border-red-600 hover:bg-red-700"
1644
+ }
1645
+ }[t.variant];
1646
+ return r.value ? e.dark : e.light;
1647
+ });
1648
+ return (t, n) => (_(), a("button", {
1649
+ type: e.type,
1650
+ disabled: e.disabled,
1651
+ title: e.title,
1652
+ class: f(["inline-flex shrink-0 items-center gap-2 px-3 py-2 rounded-lg text-sm font-medium border transition-colors cursor-pointer disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap", o.value]),
1653
+ onClick: n[0] ||= (e) => t.$emit("click", e)
1654
+ }, [b(t.$slots, "icon", { iconClass: "w-4 h-4" }), e.label ? (_(), a("span", vn, C(e.label), 1)) : i("", !0)], 10, _n));
1655
+ }
1656
+ }), bn = [
1657
+ "type",
1658
+ "disabled",
1659
+ "title",
1660
+ "aria-label"
1661
+ ], xn = { key: 0 }, Sn = /* @__PURE__ */ l({
1662
+ __name: "BaseActionButton",
1663
+ props: {
1664
+ label: { default: "" },
1665
+ color: { default: "emerald" },
1666
+ disabled: {
1667
+ type: Boolean,
1668
+ default: !1
1669
+ },
1670
+ fullWidth: {
1671
+ type: Boolean,
1672
+ default: !1
1673
+ },
1674
+ title: { default: void 0 },
1675
+ ariaLabel: { default: void 0 },
1676
+ type: { default: "button" }
1677
+ },
1678
+ emits: ["click"],
1679
+ setup(e) {
1680
+ let t = e, { isDark: r } = Y(), o = n(() => {
1681
+ let e = {
1682
+ emerald: {
1683
+ dark: "text-emerald-400 hover:bg-emerald-500/10",
1684
+ light: "text-emerald-600 hover:bg-emerald-50"
1685
+ },
1686
+ sky: {
1687
+ dark: "text-sky-400 hover:bg-sky-500/10",
1688
+ light: "text-sky-600 hover:bg-sky-50"
1689
+ },
1690
+ indigo: {
1691
+ dark: "text-indigo-400 hover:bg-indigo-500/10",
1692
+ light: "text-indigo-600 hover:bg-indigo-50"
1693
+ },
1694
+ teal: {
1695
+ dark: "text-teal-400 hover:bg-teal-500/10",
1696
+ light: "text-teal-600 hover:bg-teal-50"
1697
+ },
1698
+ purple: {
1699
+ dark: "text-purple-400 hover:bg-purple-500/10",
1700
+ light: "text-purple-600 hover:bg-purple-50"
1701
+ },
1702
+ red: {
1703
+ dark: "text-red-400 hover:bg-red-500/10",
1704
+ light: "text-red-500 hover:bg-red-50"
1705
+ },
1706
+ amber: {
1707
+ dark: "text-amber-400 hover:bg-amber-500/10",
1708
+ light: "text-amber-600 hover:bg-amber-50"
1709
+ },
1710
+ amberStrong: {
1711
+ dark: "text-amber-300 hover:bg-amber-500/10",
1712
+ light: "text-amber-700 hover:bg-amber-50"
1713
+ }
1714
+ }[t.color];
1715
+ return r.value ? e.dark : e.light;
1716
+ }), s = n(() => {
1717
+ let e = {
1718
+ emerald: {
1719
+ dark: "text-emerald-400",
1720
+ light: "text-emerald-600"
1721
+ },
1722
+ sky: {
1723
+ dark: "text-sky-400",
1724
+ light: "text-sky-600"
1725
+ },
1726
+ indigo: {
1727
+ dark: "text-indigo-400",
1728
+ light: "text-indigo-600"
1729
+ },
1730
+ teal: {
1731
+ dark: "text-teal-400",
1732
+ light: "text-teal-600"
1733
+ },
1734
+ purple: {
1735
+ dark: "text-purple-400",
1736
+ light: "text-purple-600"
1737
+ },
1738
+ red: {
1739
+ dark: "text-red-400",
1740
+ light: "text-red-500"
1741
+ },
1742
+ amber: {
1743
+ dark: "text-amber-400",
1744
+ light: "text-amber-600"
1745
+ },
1746
+ amberStrong: {
1747
+ dark: "text-amber-300",
1748
+ light: "text-amber-700"
1749
+ }
1750
+ }[t.color];
1751
+ return r.value ? e.dark : e.light;
1752
+ }), c = n(() => t.disabled ? `${s.value} opacity-50 cursor-not-allowed` : `${o.value} cursor-pointer`);
1753
+ return (t, n) => (_(), a("button", {
1754
+ type: e.type,
1755
+ disabled: e.disabled,
1756
+ title: e.title,
1757
+ "aria-label": e.ariaLabel,
1758
+ class: f(["inline-flex items-center justify-center gap-1.5 px-3 py-1.5 rounded-lg text-xs font-medium transition-colors", [e.fullWidth ? "flex-1" : "", c.value]]),
1759
+ onClick: n[0] ||= (e) => t.$emit("click", e)
1760
+ }, [b(t.$slots, "icon", { iconClass: "w-4 h-4" }), e.label ? (_(), a("span", xn, C(e.label), 1)) : i("", !0)], 10, bn));
1761
+ }
1561
1762
  });
1562
1763
  //#endregion
1563
1764
  //#region src/composables/useDebounce.ts
1564
- function pn(e, t = 300) {
1765
+ function Cn(e, t = 300) {
1565
1766
  let n = v(e.value), r = null;
1566
1767
  return O(e, (e) => {
1567
1768
  r && clearTimeout(r), r = setTimeout(() => {
@@ -1573,7 +1774,7 @@ function pn(e, t = 300) {
1573
1774
  }
1574
1775
  //#endregion
1575
1776
  //#region src/composables/useToast.ts
1576
- function mn(e = 3e3) {
1777
+ function wn(e = 3e3) {
1577
1778
  let t = v(!1), n = v(""), r = v(G.SUCCESS), i = null;
1578
1779
  function a() {
1579
1780
  i &&= (clearTimeout(i), null);
@@ -1594,16 +1795,16 @@ function mn(e = 3e3) {
1594
1795
  }
1595
1796
  //#endregion
1596
1797
  //#region src/enums/BaseBadgeEnum.ts
1597
- var hn = /* @__PURE__ */ function(e) {
1798
+ var Tn = /* @__PURE__ */ function(e) {
1598
1799
  return e.WIN = "WIN", e.LOSE = "LOSE", e;
1599
- }({}), gn = {
1800
+ }({}), En = {
1600
1801
  GET: "bg-blue-600",
1601
1802
  POST: "bg-emerald-600",
1602
1803
  PUT: "bg-amber-600",
1603
1804
  DELETE: "bg-red-600",
1604
1805
  PATCH: "bg-purple-600",
1605
1806
  HEAD: "bg-gray-600"
1606
- }, _n = {
1807
+ }, Dn = {
1607
1808
  GET: "bg-blue-500",
1608
1809
  POST: "bg-green-500",
1609
1810
  PUT: "bg-yellow-500",
@@ -1611,19 +1812,137 @@ var hn = /* @__PURE__ */ function(e) {
1611
1812
  PATCH: "bg-purple-500",
1612
1813
  HEAD: "bg-gray-500"
1613
1814
  };
1614
- function vn(e) {
1615
- return e ? gn[e.toUpperCase()] ?? "bg-gray-600" : "bg-gray-600";
1815
+ function On(e) {
1816
+ return e ? En[e.toUpperCase()] ?? "bg-gray-600" : "bg-gray-600";
1616
1817
  }
1617
- function yn(e) {
1618
- return e ? _n[e.toUpperCase()] ?? "bg-gray-500" : "bg-gray-500";
1818
+ function kn(e) {
1819
+ return e ? Dn[e.toUpperCase()] ?? "bg-gray-500" : "bg-gray-500";
1619
1820
  }
1620
- function bn(e) {
1821
+ function An(e) {
1621
1822
  let t = e ?? 0;
1622
1823
  return t >= 200 && t < 300 ? "bg-emerald-600" : t >= 300 && t < 400 ? "bg-blue-600" : t >= 400 && t < 500 ? "bg-amber-600" : t >= 500 ? "bg-red-600" : "bg-gray-600";
1623
1824
  }
1624
- function xn(e, t) {
1825
+ function jn(e, t) {
1625
1826
  let n = e ?? 200;
1626
1827
  return t ? n >= 200 && n < 300 ? "bg-green-500/15 text-green-400" : n >= 300 && n < 400 ? "bg-blue-500/15 text-blue-400" : n >= 400 && n < 500 ? "bg-yellow-500/15 text-yellow-400" : "bg-red-500/15 text-red-400" : n >= 200 && n < 300 ? "bg-green-100 text-green-800" : n >= 300 && n < 400 ? "bg-blue-100 text-blue-800" : n >= 400 && n < 500 ? "bg-yellow-100 text-yellow-800" : "bg-red-100 text-red-800";
1627
1828
  }
1628
1829
  //#endregion
1629
- export { I as AlertEnum, he as BaseAlert, fn as BaseAppLayout, R as BaseBadge, hn as BaseBadgeEnum, be as BaseBreadcrumb, ke as BaseButton, z as BaseButtonEnum, B as BaseButtonSizeEnum, Ot as BaseCollapsibleSection, Mt as BaseConfirmModal, ln as BaseEntityPickerModal, Ne as BaseLine, Pe as BaseLoginEnum, Ie as BaseLogo, H as BaseLogoEnum, He as BaseModal, U as BaseModalEnum, Q as BaseModalShell, zt as BaseNotFoundPage, Ue as BaseRow, Yt as BaseSidebar, qe as BaseSpinner, It as BaseTextInputModal, Ze as BaseToast, G as BaseToastEnum, $e as ColoredSquares, L as ColorsEnums, ot as EarningsCard, dt as EuroAmount, V as LineEnum, mt as Pagination, K as PositioningEnum, vt as TrendArrow, fe as getBaseColor, pe as getBaseColorOf, yn as methodBadgeBright, vn as methodBadgeSolid, bn as statusBadgeSolid, xn as statusBadgeTinted, pn as useDebouncedRef, Z as useEscapeKey, Bt as useMobileSidebar, Y as useTheme, X as useThemeClasses, mn as useToast };
1830
+ //#region src/utils/sanitizeHtml.ts
1831
+ var Mn = new Set([
1832
+ "A",
1833
+ "B",
1834
+ "STRONG",
1835
+ "I",
1836
+ "EM",
1837
+ "CODE",
1838
+ "PRE",
1839
+ "BR",
1840
+ "P",
1841
+ "UL",
1842
+ "OL",
1843
+ "LI",
1844
+ "SPAN",
1845
+ "DIV"
1846
+ ]), Nn = new Set([
1847
+ "SCRIPT",
1848
+ "STYLE",
1849
+ "IFRAME",
1850
+ "OBJECT",
1851
+ "EMBED",
1852
+ "NOSCRIPT",
1853
+ "TEMPLATE"
1854
+ ]), Pn = { A: new Set(["href", "title"]) };
1855
+ function Fn(e) {
1856
+ let t = e.trim().toLowerCase();
1857
+ return t.startsWith("http://") || t.startsWith("https://") || t.startsWith("mailto:") || t.startsWith("tel:") || t.startsWith("/") || t.startsWith("#") || t === "";
1858
+ }
1859
+ function In(e) {
1860
+ if (e.nodeType !== Node.ELEMENT_NODE) return;
1861
+ let t = e, n = t.tagName.toUpperCase();
1862
+ if (!Mn.has(n)) {
1863
+ Nn.has(n) ? t.remove() : t.replaceWith(document.createTextNode(t.textContent ?? ""));
1864
+ return;
1865
+ }
1866
+ let r = Pn[n] ?? /* @__PURE__ */ new Set();
1867
+ for (let e of Array.from(t.attributes)) {
1868
+ if (!r.has(e.name.toLowerCase())) {
1869
+ t.removeAttribute(e.name);
1870
+ continue;
1871
+ }
1872
+ n === "A" && e.name.toLowerCase() === "href" && !Fn(e.value) && t.removeAttribute(e.name);
1873
+ }
1874
+ n === "A" && t.hasAttribute("href") && (t.setAttribute("rel", "noopener noreferrer"), t.setAttribute("target", "_blank"));
1875
+ for (let e of Array.from(t.childNodes)) In(e);
1876
+ }
1877
+ function Ln(e) {
1878
+ if (!e) return "";
1879
+ let t = new DOMParser().parseFromString(`<div>${e}</div>`, "text/html").body.firstElementChild;
1880
+ if (!t) return "";
1881
+ for (let e of Array.from(t.childNodes)) In(e);
1882
+ return t.innerHTML;
1883
+ }
1884
+ //#endregion
1885
+ //#region src/utils/format.ts
1886
+ var Rn = "—";
1887
+ function zn(e, t = 4) {
1888
+ if (e == null) return Rn;
1889
+ let n = typeof e == "string" ? Number(e) : e;
1890
+ return isFinite(n) ? n.toLocaleString(void 0, {
1891
+ minimumFractionDigits: t,
1892
+ maximumFractionDigits: t
1893
+ }) : Rn;
1894
+ }
1895
+ function Bn(e) {
1896
+ if (e == null || e === "") return Rn;
1897
+ try {
1898
+ return new Date(e).toLocaleString();
1899
+ } catch {
1900
+ return String(e);
1901
+ }
1902
+ }
1903
+ function Vn(e) {
1904
+ return new Date(e).toLocaleString(void 0, {
1905
+ month: "short",
1906
+ day: "numeric",
1907
+ hour: "2-digit",
1908
+ minute: "2-digit"
1909
+ });
1910
+ }
1911
+ function Hn(e) {
1912
+ return new Date(e).toLocaleDateString(void 0, {
1913
+ month: "short",
1914
+ day: "numeric"
1915
+ });
1916
+ }
1917
+ function Un(e) {
1918
+ if (!isFinite(e) || e === 0) return e.toFixed(2);
1919
+ let t = Math.abs(e), n = 2;
1920
+ return t < 1e-4 ? n = 8 : t < .01 ? n = 6 : t < 1 ? n = 4 : t < 100 && (n = 3), e.toLocaleString(void 0, {
1921
+ minimumFractionDigits: n,
1922
+ maximumFractionDigits: n
1923
+ });
1924
+ }
1925
+ function Wn(e, t = 2) {
1926
+ return `${e >= 0 ? "+" : ""}${e.toFixed(t)}%`;
1927
+ }
1928
+ function Gn(e) {
1929
+ return `${e >= 0 ? "+" : ""}$${e.toFixed(2)}`;
1930
+ }
1931
+ //#endregion
1932
+ //#region src/utils/pnl.ts
1933
+ function Kn(e) {
1934
+ if (e.buyPrice == null || e.lastPrice == null || e.filledQty == null) return {
1935
+ pnlUsd: null,
1936
+ pnlPct: null
1937
+ };
1938
+ let t = Number(e.buyPrice), n = Number(e.lastPrice), r = Number(e.filledQty);
1939
+ return !isFinite(t) || !isFinite(n) || !isFinite(r) || t <= 0 ? {
1940
+ pnlUsd: null,
1941
+ pnlPct: null
1942
+ } : {
1943
+ pnlUsd: (n - t) * r,
1944
+ pnlPct: (n - t) / t * 100
1945
+ };
1946
+ }
1947
+ //#endregion
1948
+ export { I as AlertEnum, Sn as BaseActionButton, he as BaseAlert, fn as BaseAppLayout, R as BaseBadge, Tn as BaseBadgeEnum, be as BaseBreadcrumb, ke as BaseButton, z as BaseButtonEnum, B as BaseButtonSizeEnum, Ot as BaseCollapsibleSection, Mt as BaseConfirmModal, ln as BaseEntityPickerModal, Ne as BaseLine, Pe as BaseLoginEnum, Ie as BaseLogo, H as BaseLogoEnum, He as BaseModal, U as BaseModalEnum, Q as BaseModalShell, zt as BaseNotFoundPage, gn as BasePageHeader, Ue as BaseRow, Yt as BaseSidebar, qe as BaseSpinner, It as BaseTextInputModal, Ze as BaseToast, G as BaseToastEnum, yn as BaseToolbarButton, $e as ColoredSquares, L as ColorsEnums, ot as EarningsCard, dt as EuroAmount, V as LineEnum, mt as Pagination, K as PositioningEnum, vt as TrendArrow, Kn as computePnL, Bn as fmtDate, Hn as fmtDateShort, Vn as fmtDateTime, zn as fmtNumber, Wn as fmtPct, Un as fmtPrice, Gn as fmtUsd, fe as getBaseColor, pe as getBaseColorOf, Fn as isSafeHref, kn as methodBadgeBright, On as methodBadgeSolid, Ln as sanitizeHtml, An as statusBadgeSolid, jn as statusBadgeTinted, Cn as useDebouncedRef, Z as useEscapeKey, Bt as useMobileSidebar, Y as useTheme, X as useThemeClasses, wn as useToast };