@retinalabsllc/zairusjs 0.2.2 → 0.2.4

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.js CHANGED
@@ -55,6 +55,12 @@ __export(index_exports, {
55
55
  TextInput: () => TextInput,
56
56
  ThreeDActionButton: () => ThreeDActionButton,
57
57
  ThreeDButton: () => ThreeDButton,
58
+ UniversalHeader: () => UniversalHeader,
59
+ UniversalIdentityPage: () => UniversalIdentityPage,
60
+ UniversalMembersPage: () => UniversalMembersPage,
61
+ UniversalOrganizationPage: () => UniversalOrganizationPage,
62
+ UniversalProfileSettings: () => UniversalProfileSettings,
63
+ UniversalSidebar: () => UniversalSidebar,
58
64
  ZairusAuth: () => ZairusAuth
59
65
  });
60
66
  module.exports = __toCommonJS(index_exports);
@@ -1124,12 +1130,11 @@ var PageSpinner = ({
1124
1130
  // src/components/ManagedToaster.tsx
1125
1131
  var import_react29 = __toESM(require("react"));
1126
1132
  var import_react_hot_toast2 = require("react-hot-toast");
1127
- var ManagedToaster = (props) => {
1133
+ var ManagedToaster = () => {
1128
1134
  return /* @__PURE__ */ import_react29.default.createElement(
1129
1135
  import_react_hot_toast2.Toaster,
1130
1136
  {
1131
1137
  position: "top-right",
1132
- ...props,
1133
1138
  toastOptions: {
1134
1139
  style: {
1135
1140
  background: "#171717",
@@ -1151,9 +1156,7 @@ var ManagedToaster = (props) => {
1151
1156
  primary: "#fafafa",
1152
1157
  secondary: "#171717"
1153
1158
  }
1154
- },
1155
- ...props.toastOptions
1156
- // Allows overriding specific toast styles if needed
1159
+ }
1157
1160
  }
1158
1161
  }
1159
1162
  );
@@ -1486,6 +1489,888 @@ var GifFeatureCard = ({
1486
1489
  }
1487
1490
  ), /* @__PURE__ */ import_react35.default.createElement("div", { className: "absolute inset-x-0 bottom-0 p-6 sm:p-8 z-30 flex flex-col justify-end text-left pointer-events-none" }, title && /* @__PURE__ */ import_react35.default.createElement("h3", { className: "text-xl sm:text-2xl md:text-3xl font-medium text-white tracking-tight mb-2 sm:mb-3 drop-shadow-md" }, title), subtitle && /* @__PURE__ */ import_react35.default.createElement("p", { className: "text-[13px] sm:text-[15px] leading-relaxed text-neutral-300 max-w-2xl drop-shadow-sm" }, subtitle)));
1488
1491
  };
1492
+
1493
+ // src/components/UniversalSidebar.tsx
1494
+ var import_react37 = __toESM(require("react"));
1495
+ var import_link10 = __toESM(require("next/link"));
1496
+ var import_react38 = require("@hugeicons/react");
1497
+ var import_core_free_icons9 = require("@hugeicons/core-free-icons");
1498
+ var UniversalSidebar = ({
1499
+ navItems,
1500
+ currentPath,
1501
+ isMobileOpen,
1502
+ closeMobile,
1503
+ onNavClick,
1504
+ showInterceptDialog = false,
1505
+ onCancelIntercept,
1506
+ onConfirmIntercept,
1507
+ interceptTitle = "Discard Changes",
1508
+ interceptMessage = "Are you sure you want to leave? All unsaved changes will be lost."
1509
+ }) => {
1510
+ const [isCollapsed, setIsCollapsed] = (0, import_react37.useState)(false);
1511
+ (0, import_react37.useEffect)(() => {
1512
+ if (isMobileOpen) {
1513
+ closeMobile();
1514
+ }
1515
+ }, [currentPath]);
1516
+ return /* @__PURE__ */ import_react37.default.createElement(import_react37.default.Fragment, null, /* @__PURE__ */ import_react37.default.createElement(
1517
+ "div",
1518
+ {
1519
+ className: `fixed inset-0 bg-black/30 shadow-2xl transition-opacity duration-300 md:hidden z-90 ${isMobileOpen ? "opacity-100 pointer-events-auto" : "opacity-0 pointer-events-none"}`,
1520
+ onClick: closeMobile
1521
+ }
1522
+ ), /* @__PURE__ */ import_react37.default.createElement(
1523
+ "aside",
1524
+ {
1525
+ className: `
1526
+ fixed md:relative top-0 left-0 h-full bg-white
1527
+ transition-all duration-300 ease-in-out shrink-0 flex flex-col z-100 md:z-10
1528
+ ${isMobileOpen ? "translate-x-0" : "-translate-x-full md:translate-x-0"}
1529
+ ${isCollapsed ? "md:w-16 w-64" : "w-64"}
1530
+ `
1531
+ },
1532
+ /* @__PURE__ */ import_react37.default.createElement("div", { className: "md:hidden flex justify-end p-4 shrink-0" }, /* @__PURE__ */ import_react37.default.createElement(
1533
+ "button",
1534
+ {
1535
+ onClick: closeMobile,
1536
+ className: "text-neutral-400 hover:text-black transition-colors outline-none",
1537
+ "aria-label": "Close Menu"
1538
+ },
1539
+ /* @__PURE__ */ import_react37.default.createElement(import_react38.HugeiconsIcon, { icon: import_core_free_icons9.Cancel01Icon, size: 24 })
1540
+ )),
1541
+ /* @__PURE__ */ import_react37.default.createElement("nav", { className: "flex-1 py-6 flex flex-col gap-1.5 px-3 overflow-y-auto custom-scrollbar" }, navItems.map((item) => {
1542
+ const isCurrentRoute = item.path === "/mod" || item.path === "/app" ? currentPath === item.path : currentPath === item.path || currentPath?.startsWith(`${item.path}/`);
1543
+ return /* @__PURE__ */ import_react37.default.createElement(
1544
+ import_link10.default,
1545
+ {
1546
+ key: item.name,
1547
+ href: item.path,
1548
+ onClick: (e) => onNavClick ? onNavClick(e, item.path) : void 0,
1549
+ className: `flex items-center gap-3 px-3 py-2 rounded-full transition-all outline-none group ${isCurrentRoute ? "bg-neutral-100 text-black " : "text-neutral-500 hover:text-black hover:bg-neutral-50"}`,
1550
+ title: isCollapsed && !isMobileOpen ? item.name : void 0
1551
+ },
1552
+ /* @__PURE__ */ import_react37.default.createElement(
1553
+ import_react38.HugeiconsIcon,
1554
+ {
1555
+ icon: item.icon,
1556
+ size: 18,
1557
+ className: `shrink-0 transition-colors ${isCurrentRoute ? "text-black" : "text-neutral-400 group-hover:text-black"}`
1558
+ }
1559
+ ),
1560
+ (!isCollapsed || isMobileOpen) && /* @__PURE__ */ import_react37.default.createElement("span", { className: "text-xs tracking-wide truncate" }, item.name)
1561
+ );
1562
+ })),
1563
+ /* @__PURE__ */ import_react37.default.createElement("div", { className: "p-4 hidden md:block shrink-0" }, /* @__PURE__ */ import_react37.default.createElement(
1564
+ "button",
1565
+ {
1566
+ onClick: () => setIsCollapsed(!isCollapsed),
1567
+ className: "flex items-center justify-center md:justify-start gap-3 w-full p-2.5 rounded-full text-neutral-500 hover:text-black hover:bg-neutral-50 transition-colors outline-none"
1568
+ },
1569
+ /* @__PURE__ */ import_react37.default.createElement(import_react38.HugeiconsIcon, { icon: import_core_free_icons9.SidebarLeft01Icon, size: 18, className: "shrink-0 text-neutral-400" }),
1570
+ !isCollapsed && /* @__PURE__ */ import_react37.default.createElement("span", { className: "text-xs" }, "Collapse")
1571
+ ))
1572
+ ), showInterceptDialog && /* @__PURE__ */ import_react37.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react37.default.createElement(
1573
+ "div",
1574
+ {
1575
+ className: "absolute inset-0 bg-black/30",
1576
+ onClick: onCancelIntercept
1577
+ }
1578
+ ), /* @__PURE__ */ import_react37.default.createElement("div", { className: "relative w-72 bg-white rounded-2xl flex flex-col items-center overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react37.default.createElement("div", { className: "p-6 text-center w-full" }, /* @__PURE__ */ import_react37.default.createElement("h3", { className: "text-[14px] text-black tracking-tight mb-1" }, interceptTitle), /* @__PURE__ */ import_react37.default.createElement("p", { className: "text-[12px] text-neutral-500 leading-snug mt-2" }, interceptMessage)), /* @__PURE__ */ import_react37.default.createElement("div", { className: "w-full flex" }, /* @__PURE__ */ import_react37.default.createElement(
1579
+ "button",
1580
+ {
1581
+ onClick: onCancelIntercept,
1582
+ className: "flex-1 py-2 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors outline-none"
1583
+ },
1584
+ "Cancel"
1585
+ ), /* @__PURE__ */ import_react37.default.createElement(
1586
+ "button",
1587
+ {
1588
+ onClick: onConfirmIntercept,
1589
+ className: "flex-1 py-2 text-[13px] text-[#F16A50] hover:bg-neutral-50 transition-colors flex justify-center items-center outline-none"
1590
+ },
1591
+ "Leave"
1592
+ )))));
1593
+ };
1594
+
1595
+ // src/components/UniversalHeader.tsx
1596
+ var import_react39 = __toESM(require("react"));
1597
+ var import_link11 = __toESM(require("next/link"));
1598
+ var import_react40 = require("@hugeicons/react");
1599
+ var import_core_free_icons10 = require("@hugeicons/core-free-icons");
1600
+ var ButtonSpinner = () => /* @__PURE__ */ import_react39.default.createElement("svg", { className: "animate-spin h-4 w-4 text-neutral-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ import_react39.default.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ import_react39.default.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
1601
+ var UniversalHeader = ({
1602
+ onOpenMobile,
1603
+ title,
1604
+ subtitle,
1605
+ homeUrl = "/app",
1606
+ showBackButton = false,
1607
+ backUrl = "/app",
1608
+ showWorkspaceSwitcher = false,
1609
+ workspaces = [],
1610
+ activeWorkspaceId,
1611
+ onSwitchWorkspace,
1612
+ showLogoutAction = false,
1613
+ onLogout
1614
+ }) => {
1615
+ const [showSwitcherDialog, setShowSwitcherDialog] = (0, import_react39.useState)(false);
1616
+ const [showLogoutDialog, setShowLogoutDialog] = (0, import_react39.useState)(false);
1617
+ const [isLoggingOut, setIsLoggingOut] = (0, import_react39.useState)(false);
1618
+ const handleLogoutInitiation = async () => {
1619
+ if (isLoggingOut || !onLogout) return;
1620
+ setIsLoggingOut(true);
1621
+ try {
1622
+ await onLogout();
1623
+ } catch (error) {
1624
+ setIsLoggingOut(false);
1625
+ setShowLogoutDialog(false);
1626
+ }
1627
+ };
1628
+ return /* @__PURE__ */ import_react39.default.createElement("div", { className: "w-full shrink-0 z-50 flex flex-col relative pointer-events-none" }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "w-full pointer-events-auto relative z-20" }, /* @__PURE__ */ import_react39.default.createElement("header", { className: "w-full bg-white pt-6 pb-3" }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "max-w-7xl mx-auto px-6 flex justify-between items-center" }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "flex items-center gap-4" }, /* @__PURE__ */ import_react39.default.createElement(
1629
+ "button",
1630
+ {
1631
+ className: "md:hidden text-neutral-500 hover:text-black transition-colors outline-none",
1632
+ onClick: onOpenMobile,
1633
+ "aria-label": "Open Menu"
1634
+ },
1635
+ /* @__PURE__ */ import_react39.default.createElement(import_react40.HugeiconsIcon, { icon: import_core_free_icons10.SidebarLeft01Icon, size: 24 })
1636
+ ), /* @__PURE__ */ import_react39.default.createElement(import_link11.default, { href: homeUrl, className: "flex items-center gap-3 transition-opacity hover:opacity-70 outline-none" }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "flex flex-col justify-center" }, /* @__PURE__ */ import_react39.default.createElement("span", { className: "text-[13px] text-black leading-none truncate tracking-wide mb-1" }, title), subtitle && /* @__PURE__ */ import_react39.default.createElement("span", { className: "text-[9px] text-neutral-500 truncate tracking-[0.2em] leading-none" }, subtitle)))), /* @__PURE__ */ import_react39.default.createElement("div", { className: "flex items-center gap-3" }, showWorkspaceSwitcher && workspaces.length > 0 && /* @__PURE__ */ import_react39.default.createElement(
1637
+ "button",
1638
+ {
1639
+ onClick: () => setShowSwitcherDialog(true),
1640
+ className: "w-10 h-10 rounded-full border border-neutral-200 bg-white flex items-center justify-center text-neutral-500 hover:text-black hover:border-black hover:bg-neutral-50 transition-all group outline-none",
1641
+ "aria-label": "Switch Workspace"
1642
+ },
1643
+ /* @__PURE__ */ import_react39.default.createElement(import_react40.HugeiconsIcon, { icon: import_core_free_icons10.ArrowDataTransferHorizontalIcon, size: 16, className: "transition-transform group-hover:-translate-x-0.5" })
1644
+ ), showLogoutAction && /* @__PURE__ */ import_react39.default.createElement(
1645
+ "button",
1646
+ {
1647
+ onClick: () => setShowLogoutDialog(true),
1648
+ className: "w-10 h-10 rounded-full border border-neutral-200 bg-white flex items-center justify-center text-neutral-500 hover:text-black hover:border-black hover:bg-neutral-50 transition-all group outline-none",
1649
+ "aria-label": "Secure Logout"
1650
+ },
1651
+ /* @__PURE__ */ import_react39.default.createElement(import_react40.HugeiconsIcon, { icon: import_core_free_icons10.LogoutCircle02Icon, size: 16, className: "transition-transform group-hover:-translate-x-0.5" })
1652
+ ), showBackButton && /* @__PURE__ */ import_react39.default.createElement(
1653
+ import_link11.default,
1654
+ {
1655
+ href: backUrl,
1656
+ className: "flex items-center justify-center w-10 h-10 border border-neutral-200 bg-white rounded-full text-neutral-500 hover:text-black hover:border-black hover:bg-neutral-50 transition-all group outline-none",
1657
+ "aria-label": "Go Back"
1658
+ },
1659
+ /* @__PURE__ */ import_react39.default.createElement(import_react40.HugeiconsIcon, { icon: import_core_free_icons10.ArrowLeft01Icon, size: 16, className: "transition-transform group-hover:-translate-x-0.5" })
1660
+ ))))), showSwitcherDialog && showWorkspaceSwitcher && workspaces.length > 0 && /* @__PURE__ */ import_react39.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react39.default.createElement(
1661
+ "div",
1662
+ {
1663
+ className: "absolute inset-0 bg-black/30",
1664
+ onClick: () => setShowSwitcherDialog(false)
1665
+ }
1666
+ ), /* @__PURE__ */ import_react39.default.createElement("div", { className: "relative w-full max-w-sm bg-white rounded-2xl flex flex-col overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "p-5 text-center w-full" }, /* @__PURE__ */ import_react39.default.createElement("h3", { className: "text-[14px] text-black tracking-tight mb-1" }, "Switch Workspace"), /* @__PURE__ */ import_react39.default.createElement("p", { className: "text-[11px] text-neutral-500 leading-snug" }, "Select an organization to switch your current context.")), /* @__PURE__ */ import_react39.default.createElement("div", { className: "max-h-75 overflow-y-auto w-full custom-scrollbar" }, workspaces.map((org) => /* @__PURE__ */ import_react39.default.createElement(
1667
+ "button",
1668
+ {
1669
+ key: org.id,
1670
+ onClick: () => {
1671
+ if (onSwitchWorkspace) onSwitchWorkspace(org.id);
1672
+ setShowSwitcherDialog(false);
1673
+ },
1674
+ className: "w-full text-left px-5 py-4 flex items-center justify-between hover:bg-neutral-50 transition-colors group outline-none last:border-0"
1675
+ },
1676
+ /* @__PURE__ */ import_react39.default.createElement("div", { className: "flex flex-col truncate pr-4" }, /* @__PURE__ */ import_react39.default.createElement("span", { className: `text-[13px] truncate ${activeWorkspaceId === org.id ? "text-black" : "text-neutral-600 group-hover:text-black"}` }, org.name), /* @__PURE__ */ import_react39.default.createElement("span", { className: "text-[9px] text-neutral-400 tracking-[0.2em] mt-1" }, "Role: ", org.role)),
1677
+ activeWorkspaceId === org.id && /* @__PURE__ */ import_react39.default.createElement(import_react40.HugeiconsIcon, { icon: import_core_free_icons10.CheckmarkCircle01Icon, size: 18, className: "text-black shrink-0" })
1678
+ ))), /* @__PURE__ */ import_react39.default.createElement("div", { className: "w-full flex mt-auto" }, /* @__PURE__ */ import_react39.default.createElement(
1679
+ "button",
1680
+ {
1681
+ onClick: () => setShowSwitcherDialog(false),
1682
+ className: "w-full py-2.5 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors outline-none"
1683
+ },
1684
+ "Cancel"
1685
+ )))), showLogoutDialog && showLogoutAction && /* @__PURE__ */ import_react39.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4 pointer-events-auto" }, /* @__PURE__ */ import_react39.default.createElement(
1686
+ "div",
1687
+ {
1688
+ className: "absolute inset-0 bg-black/30",
1689
+ onClick: () => !isLoggingOut && setShowLogoutDialog(false)
1690
+ }
1691
+ ), /* @__PURE__ */ import_react39.default.createElement("div", { className: "relative w-72 bg-white rounded-2xl flex flex-col items-center overflow-hidden shadow-2xl animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react39.default.createElement("div", { className: "p-6 text-center w-full" }, /* @__PURE__ */ import_react39.default.createElement("h3", { className: "text-[14px] text-black tracking-tight mb-1" }, "Secure Logout"), /* @__PURE__ */ import_react39.default.createElement("p", { className: "text-[12px] text-neutral-500 leading-snug mt-2" }, "Are you sure you want to log out? You will need to authenticate to return.")), /* @__PURE__ */ import_react39.default.createElement("div", { className: "w-full flex" }, /* @__PURE__ */ import_react39.default.createElement(
1692
+ "button",
1693
+ {
1694
+ onClick: () => setShowLogoutDialog(false),
1695
+ disabled: isLoggingOut,
1696
+ className: "flex-1 py-2 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors disabled:opacity-50 outline-none"
1697
+ },
1698
+ "Cancel"
1699
+ ), /* @__PURE__ */ import_react39.default.createElement(
1700
+ "button",
1701
+ {
1702
+ onClick: handleLogoutInitiation,
1703
+ disabled: isLoggingOut,
1704
+ className: "flex-1 py-2 text-[13px] text-[#F16A50] hover:bg-neutral-50 transition-colors disabled:opacity-50 flex justify-center items-center outline-none"
1705
+ },
1706
+ isLoggingOut ? /* @__PURE__ */ import_react39.default.createElement(ButtonSpinner, null) : "Log Out"
1707
+ )))));
1708
+ };
1709
+
1710
+ // src/components/UniversalOrganizationPage.tsx
1711
+ var import_react41 = __toESM(require("react"));
1712
+ var import_react_hot_toast3 = __toESM(require("react-hot-toast"));
1713
+ var InputSpinner2 = () => /* @__PURE__ */ import_react41.default.createElement("svg", { className: "animate-spin h-4 w-4 text-neutral-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ import_react41.default.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ import_react41.default.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
1714
+ var UniversalOrganizationPage = ({
1715
+ initialOrgName,
1716
+ initialSlug,
1717
+ orgId,
1718
+ isReadOnly = false,
1719
+ slugPrefixUrl = "ecosystem.com/org/",
1720
+ onSaveConfiguration,
1721
+ onCheckSlugAvailability
1722
+ }) => {
1723
+ const [orgName, setOrgName] = (0, import_react41.useState)(initialOrgName);
1724
+ const [slug, setSlug] = (0, import_react41.useState)(initialSlug);
1725
+ const [isCheckingSlug, setIsCheckingSlug] = (0, import_react41.useState)(false);
1726
+ const [slugAvailable, setSlugAvailable] = (0, import_react41.useState)(null);
1727
+ const [isSubmitting, setIsSubmitting] = (0, import_react41.useState)(false);
1728
+ (0, import_react41.useEffect)(() => {
1729
+ setOrgName(initialOrgName || "");
1730
+ setSlug(initialSlug || "");
1731
+ }, [initialOrgName, initialSlug]);
1732
+ const handleOrgNameChange = (val) => {
1733
+ setOrgName(val.replace(/[^a-zA-Z0-9\s-]/g, "").substring(0, 50));
1734
+ };
1735
+ const handleSlugChange = (val) => {
1736
+ setSlug(val.toLowerCase().replace(/[^a-z0-9-]/g, "").replace(/-+/g, "-").substring(0, 50));
1737
+ };
1738
+ (0, import_react41.useEffect)(() => {
1739
+ if (!slug || slug === initialSlug) {
1740
+ setSlugAvailable(null);
1741
+ setIsCheckingSlug(false);
1742
+ return;
1743
+ }
1744
+ if (slug.length < 3) {
1745
+ setSlugAvailable(false);
1746
+ setIsCheckingSlug(false);
1747
+ return;
1748
+ }
1749
+ setIsCheckingSlug(true);
1750
+ setSlugAvailable(null);
1751
+ const checkTimer = setTimeout(async () => {
1752
+ try {
1753
+ const res = await onCheckSlugAvailability(slug);
1754
+ setSlugAvailable(res.available);
1755
+ } catch (error) {
1756
+ setSlugAvailable(null);
1757
+ } finally {
1758
+ setIsCheckingSlug(false);
1759
+ }
1760
+ }, 1500);
1761
+ return () => clearTimeout(checkTimer);
1762
+ }, [slug, initialSlug, onCheckSlugAvailability]);
1763
+ const handleSave = async (e) => {
1764
+ e.preventDefault();
1765
+ if (isSubmitting || isCheckingSlug || isReadOnly) return;
1766
+ if (slug !== initialSlug && slugAvailable === false) {
1767
+ import_react_hot_toast3.default.error("Please select an available workspace URL.");
1768
+ return;
1769
+ }
1770
+ setIsSubmitting(true);
1771
+ try {
1772
+ const payload = {
1773
+ organizationId: orgId,
1774
+ organizationName: orgName !== initialOrgName ? orgName : void 0,
1775
+ slug: slug !== initialSlug ? slug : void 0
1776
+ };
1777
+ const responseData = await onSaveConfiguration(payload);
1778
+ if (responseData.success) {
1779
+ import_react_hot_toast3.default.success("Organization updated successfully.");
1780
+ setTimeout(() => window.location.reload(), 1e3);
1781
+ } else {
1782
+ import_react_hot_toast3.default.error(responseData.error || "Failed to update organization.");
1783
+ setIsSubmitting(false);
1784
+ }
1785
+ } catch (error) {
1786
+ import_react_hot_toast3.default.error("Service unavailable. Try again later.");
1787
+ setIsSubmitting(false);
1788
+ }
1789
+ };
1790
+ const hasChanges = orgName !== initialOrgName || slug !== initialSlug;
1791
+ const isSaveDisabled = isSubmitting || isReadOnly || isCheckingSlug || !hasChanges || orgName.length < 3 || slug.length < 3 || slug !== initialSlug && slugAvailable === false;
1792
+ return /* @__PURE__ */ import_react41.default.createElement("div", { className: "flex flex-col gap-8 animate-in max-w-3xl rounded-2xl p-6 bg-white fade-in duration-300 min-h-full" }, /* @__PURE__ */ import_react41.default.createElement(ManagedToaster, null), /* @__PURE__ */ import_react41.default.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react41.default.createElement("div", null, /* @__PURE__ */ import_react41.default.createElement("h1", { className: "text-xl text-black mb-1 tracking-tight" }, "Organization"), /* @__PURE__ */ import_react41.default.createElement("p", { className: "text-xs text-neutral-500" }, "Manage your tenant workspace details and identity.")), isReadOnly && /* @__PURE__ */ import_react41.default.createElement("span", { className: "px-3 py-1 bg-neutral-50 text-neutral-500 rounded-full text-[10px] tracking-[0.2em] shrink-0" }, "Read Only Access")), /* @__PURE__ */ import_react41.default.createElement("div", { className: "w-full max-w-2xl" }, /* @__PURE__ */ import_react41.default.createElement("form", { className: "flex flex-col gap-8", onSubmit: handleSave, autoComplete: "off" }, /* @__PURE__ */ import_react41.default.createElement(
1793
+ TextInput,
1794
+ {
1795
+ label: "Organization Name",
1796
+ value: orgName,
1797
+ onChange: handleOrgNameChange,
1798
+ disabled: isReadOnly || isSubmitting,
1799
+ placeholder: "Acme Corporation",
1800
+ maxLength: 50
1801
+ }
1802
+ ), /* @__PURE__ */ import_react41.default.createElement("div", { className: "space-y-2 relative w-full" }, /* @__PURE__ */ import_react41.default.createElement("label", { className: "text-[10px] text-neutral-400 tracking-[0.2em] block uppercase" }, "Organization Slug"), /* @__PURE__ */ import_react41.default.createElement("div", { className: "flex items-center relative w-full" }, /* @__PURE__ */ import_react41.default.createElement("span", { className: "text-neutral-400 text-sm py-3 pr-2 border-b border-neutral-200 shrink-0" }, slugPrefixUrl), /* @__PURE__ */ import_react41.default.createElement(
1803
+ "input",
1804
+ {
1805
+ type: "text",
1806
+ value: slug,
1807
+ disabled: isReadOnly || isSubmitting,
1808
+ onChange: (e) => handleSlugChange(e.target.value),
1809
+ spellCheck: "false",
1810
+ autoComplete: "off",
1811
+ className: "w-full px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black transition-all outline-none focus:border-black pr-8 disabled:opacity-50 disabled:cursor-not-allowed",
1812
+ placeholder: "acme-corp"
1813
+ }
1814
+ ), /* @__PURE__ */ import_react41.default.createElement("div", { className: "absolute right-2 top-1/2 -translate-y-1/2" }, isCheckingSlug && /* @__PURE__ */ import_react41.default.createElement(InputSpinner2, null), !isCheckingSlug && !isReadOnly && slug !== initialSlug && slug.length >= 3 && slugAvailable === false && /* @__PURE__ */ import_react41.default.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-red-100" }, /* @__PURE__ */ import_react41.default.createElement("svg", { className: "w-2 h-2 text-red-600", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react41.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z" }))), !isCheckingSlug && !isReadOnly && slug !== initialSlug && slug.length >= 3 && slugAvailable === true && /* @__PURE__ */ import_react41.default.createElement("span", { className: "inline-flex items-center justify-center w-4 h-4 rounded-full bg-green-100" }, /* @__PURE__ */ import_react41.default.createElement("svg", { className: "w-2 h-2 text-green-600", viewBox: "0 0 20 20", fill: "currentColor" }, /* @__PURE__ */ import_react41.default.createElement("path", { fillRule: "evenodd", clipRule: "evenodd", d: "M16.707 5.293a1 1 0 00-1.414 0L8 12.586 4.707 9.293a1 1 0 10-1.414 1.414l4 4a1 1 0 001.414 0l8-8a1 1 0 000-1.414z" })))))), /* @__PURE__ */ import_react41.default.createElement("div", { className: "pt-8 mt-2 flex items-center gap-4" }, /* @__PURE__ */ import_react41.default.createElement(
1815
+ ThreeDActionButton,
1816
+ {
1817
+ type: "submit",
1818
+ disabled: isSaveDisabled,
1819
+ isLoading: isSubmitting,
1820
+ className: "min-w-32"
1821
+ },
1822
+ "Save Changes"
1823
+ ), hasChanges && !isSubmitting && !isReadOnly && /* @__PURE__ */ import_react41.default.createElement(
1824
+ "button",
1825
+ {
1826
+ type: "button",
1827
+ onClick: () => {
1828
+ setOrgName(initialOrgName);
1829
+ setSlug(initialSlug);
1830
+ },
1831
+ className: "text-[11px] tracking-widest text-neutral-500 hover:text-black transition-colors outline-none"
1832
+ },
1833
+ "Cancel"
1834
+ )))));
1835
+ };
1836
+
1837
+ // src/components/UniversalIdentityPage.tsx
1838
+ var import_react42 = __toESM(require("react"));
1839
+ var import_react_hot_toast4 = __toESM(require("react-hot-toast"));
1840
+ var ButtonSpinner2 = () => /* @__PURE__ */ import_react42.default.createElement("svg", { className: "animate-spin h-4 w-4 text-neutral-400", xmlns: "http://www.w3.org/2000/svg", fill: "none", viewBox: "0 0 24 24" }, /* @__PURE__ */ import_react42.default.createElement("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), /* @__PURE__ */ import_react42.default.createElement("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z" }));
1841
+ var UniversalIdentityPage = ({
1842
+ headerTitle,
1843
+ headerDescription,
1844
+ primaryInputLabel,
1845
+ secondaryInputLabel,
1846
+ initialPrimaryValue,
1847
+ initialSecondaryValue = "",
1848
+ resourceId,
1849
+ isReadOnly = false,
1850
+ allowDeletion = false,
1851
+ deleteWarningText = "This action will permanently delete all records and data for this entity.",
1852
+ onSaveIdentity,
1853
+ onDeleteResource,
1854
+ onSuccessfulDeleteRedirect = "/app"
1855
+ }) => {
1856
+ const [primaryValue, setPrimaryValue] = (0, import_react42.useState)(initialPrimaryValue);
1857
+ const [secondaryValue, setSecondaryValue] = (0, import_react42.useState)(initialSecondaryValue);
1858
+ const [isSubmitting, setIsSubmitting] = (0, import_react42.useState)(false);
1859
+ const [isDeleteModalOpen, setIsDeleteModalOpen] = (0, import_react42.useState)(false);
1860
+ const [isDeleting, setIsDeleting] = (0, import_react42.useState)(false);
1861
+ (0, import_react42.useEffect)(() => {
1862
+ setPrimaryValue(initialPrimaryValue || "");
1863
+ setSecondaryValue(initialSecondaryValue || "");
1864
+ }, [initialPrimaryValue, initialSecondaryValue]);
1865
+ const handlePrimaryChange = (val) => {
1866
+ setPrimaryValue(val.replace(/[^a-zA-Z0-9\s-]/g, "").substring(0, 50));
1867
+ };
1868
+ const handleSecondaryChange = (val) => {
1869
+ setSecondaryValue(val.replace(/[^a-zA-Z0-9\s.,!-]/g, "").substring(0, 150));
1870
+ };
1871
+ const handleSave = async (e) => {
1872
+ e.preventDefault();
1873
+ if (isSubmitting || isReadOnly) return;
1874
+ setIsSubmitting(true);
1875
+ try {
1876
+ const res = await onSaveIdentity({
1877
+ resourceId,
1878
+ primaryValue: primaryValue !== initialPrimaryValue ? primaryValue : void 0,
1879
+ secondaryValue: secondaryValue !== initialSecondaryValue ? secondaryValue : void 0
1880
+ });
1881
+ if (res.success) {
1882
+ import_react_hot_toast4.default.success("Update successful.");
1883
+ } else {
1884
+ import_react_hot_toast4.default.error(res.error || "Update failed.");
1885
+ }
1886
+ } catch (error) {
1887
+ import_react_hot_toast4.default.error("Service unavailable.");
1888
+ } finally {
1889
+ setIsSubmitting(false);
1890
+ }
1891
+ };
1892
+ const handleDelete = async () => {
1893
+ if (isDeleting || isReadOnly || !onDeleteResource) return;
1894
+ setIsDeleting(true);
1895
+ try {
1896
+ const res = await onDeleteResource(resourceId);
1897
+ if (res.success) {
1898
+ import_react_hot_toast4.default.success("Deletion permanent.");
1899
+ setIsDeleteModalOpen(false);
1900
+ window.location.href = onSuccessfulDeleteRedirect;
1901
+ } else {
1902
+ import_react_hot_toast4.default.error(res.error || "Failed to delete.");
1903
+ setIsDeleting(false);
1904
+ }
1905
+ } catch (error) {
1906
+ import_react_hot_toast4.default.error("Network error occurred.");
1907
+ setIsDeleting(false);
1908
+ }
1909
+ };
1910
+ const hasChanges = primaryValue !== initialPrimaryValue || secondaryValue !== initialSecondaryValue;
1911
+ const isSaveDisabled = isSubmitting || isReadOnly || !hasChanges || primaryValue.trim().length < 3;
1912
+ return /* @__PURE__ */ import_react42.default.createElement("div", { className: "flex flex-col gap-8 animate-in max-w-3xl rounded-2xl p-6 bg-white fade-in duration-300 min-h-full" }, /* @__PURE__ */ import_react42.default.createElement(ManagedToaster, null), /* @__PURE__ */ import_react42.default.createElement("div", { className: "flex items-start justify-between gap-4" }, /* @__PURE__ */ import_react42.default.createElement("div", null, /* @__PURE__ */ import_react42.default.createElement("h1", { className: "text-xl text-black mb-1 tracking-tight" }, headerTitle), /* @__PURE__ */ import_react42.default.createElement("p", { className: "text-xs text-neutral-500" }, headerDescription)), isReadOnly && /* @__PURE__ */ import_react42.default.createElement("span", { className: "px-3 py-1 bg-neutral-50 text-neutral-500 rounded-full text-[10px] tracking-[0.2em] shrink-0" }, "Read Only Access")), /* @__PURE__ */ import_react42.default.createElement("div", { className: "w-full max-w-2xl" }, /* @__PURE__ */ import_react42.default.createElement("form", { className: "flex flex-col gap-8", onSubmit: handleSave, autoComplete: "off" }, /* @__PURE__ */ import_react42.default.createElement(
1913
+ TextInput,
1914
+ {
1915
+ label: primaryInputLabel,
1916
+ value: primaryValue,
1917
+ onChange: handlePrimaryChange,
1918
+ disabled: isReadOnly || isSubmitting,
1919
+ maxLength: 50
1920
+ }
1921
+ ), secondaryInputLabel && /* @__PURE__ */ import_react42.default.createElement(
1922
+ TextInput,
1923
+ {
1924
+ label: secondaryInputLabel,
1925
+ value: secondaryValue,
1926
+ onChange: handleSecondaryChange,
1927
+ disabled: isReadOnly || isSubmitting,
1928
+ maxLength: 150
1929
+ }
1930
+ ), !isReadOnly && /* @__PURE__ */ import_react42.default.createElement("div", { className: "pt-8 mt-2 flex flex-col sm:flex-row sm:items-center justify-between gap-6" }, /* @__PURE__ */ import_react42.default.createElement("div", { className: "flex items-center gap-4 w-full sm:w-auto" }, /* @__PURE__ */ import_react42.default.createElement(
1931
+ ThreeDActionButton,
1932
+ {
1933
+ type: "submit",
1934
+ disabled: isSaveDisabled,
1935
+ isLoading: isSubmitting,
1936
+ className: "min-w-32 w-full sm:w-auto"
1937
+ },
1938
+ "Save Changes"
1939
+ ), hasChanges && !isSubmitting && /* @__PURE__ */ import_react42.default.createElement(
1940
+ "button",
1941
+ {
1942
+ type: "button",
1943
+ onClick: () => {
1944
+ setPrimaryValue(initialPrimaryValue);
1945
+ setSecondaryValue(initialSecondaryValue);
1946
+ },
1947
+ className: "text-[11px] tracking-widest text-neutral-500 hover:text-black transition-colors w-full sm:w-auto py-2 sm:py-0 outline-none"
1948
+ },
1949
+ "Cancel"
1950
+ )), allowDeletion && /* @__PURE__ */ import_react42.default.createElement(
1951
+ "button",
1952
+ {
1953
+ type: "button",
1954
+ onClick: () => setIsDeleteModalOpen(true),
1955
+ className: "px-6 py-2 text-[11px] tracking-widest text-red-400 border border-red-200 hover:border-red-400 rounded-full transition-all w-full sm:w-auto outline-none"
1956
+ },
1957
+ "Delete ",
1958
+ headerTitle.split(" ")[0]
1959
+ )))), isDeleteModalOpen && !isReadOnly && allowDeletion && /* @__PURE__ */ import_react42.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react42.default.createElement("div", { className: "absolute inset-0 bg-black/30 shadow-2xl", onClick: () => !isDeleting && setIsDeleteModalOpen(false) }), /* @__PURE__ */ import_react42.default.createElement("div", { className: "relative w-72 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react42.default.createElement("div", { className: "p-6 text-center w-full" }, /* @__PURE__ */ import_react42.default.createElement("h3", { className: "text-[14px] text-black tracking-tight mb-1" }, "Confirm Deletion"), /* @__PURE__ */ import_react42.default.createElement("p", { className: "text-[12px] text-neutral-500 leading-snug mt-2" }, deleteWarningText)), /* @__PURE__ */ import_react42.default.createElement("div", { className: "w-full flex" }, /* @__PURE__ */ import_react42.default.createElement(
1960
+ "button",
1961
+ {
1962
+ type: "button",
1963
+ onClick: () => setIsDeleteModalOpen(false),
1964
+ disabled: isDeleting,
1965
+ className: "flex-1 py-2 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors disabled:opacity-50 outline-none"
1966
+ },
1967
+ "Cancel"
1968
+ ), /* @__PURE__ */ import_react42.default.createElement(
1969
+ "button",
1970
+ {
1971
+ type: "button",
1972
+ onClick: handleDelete,
1973
+ disabled: isDeleting,
1974
+ className: "flex-1 py-2 text-[13px] text-red-600 hover:bg-neutral-50 transition-colors disabled:opacity-50 flex justify-center items-center outline-none"
1975
+ },
1976
+ isDeleting ? /* @__PURE__ */ import_react42.default.createElement(ButtonSpinner2, null) : "Delete"
1977
+ )))));
1978
+ };
1979
+
1980
+ // src/components/UniversalMembersPage.tsx
1981
+ var import_react43 = __toESM(require("react"));
1982
+ var import_react_hot_toast5 = __toESM(require("react-hot-toast"));
1983
+ var import_react44 = require("@hugeicons/react");
1984
+ var import_core_free_icons11 = require("@hugeicons/core-free-icons");
1985
+ var ButtonSpinner3 = () => /* @__PURE__ */ import_react43.default.createElement(import_react44.HugeiconsIcon, { icon: import_core_free_icons11.Loading03Icon, size: 16, className: "animate-spin text-white" });
1986
+ var PageSpinner2 = () => /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex justify-center items-center py-12" }, /* @__PURE__ */ import_react43.default.createElement(import_react44.HugeiconsIcon, { icon: import_core_free_icons11.Loading03Icon, size: 32, className: "animate-spin mb-4 text-black" }));
1987
+ var getInitials = (name) => {
1988
+ if (!name) return "U";
1989
+ const parts = name.trim().split(" ");
1990
+ if (parts.length >= 2) return (parts[0][0] + parts[parts.length - 1][0]).toUpperCase();
1991
+ return parts[0].substring(0, 2).toUpperCase();
1992
+ };
1993
+ var resolveThemeColor = (colorCode) => {
1994
+ switch (colorCode) {
1995
+ case "COLOR_A":
1996
+ return "bg-blue-100 border-blue-200";
1997
+ case "COLOR_B":
1998
+ return "bg-emerald-100 border-emerald-200";
1999
+ case "COLOR_C":
2000
+ return "bg-rose-100 border-rose-200";
2001
+ case "COLOR_D":
2002
+ return "bg-amber-100 border-amber-200";
2003
+ case "COLOR_E":
2004
+ return "bg-purple-100 border-purple-200";
2005
+ case "COLOR_F":
2006
+ return "bg-pink-100 border-pink-200";
2007
+ default:
2008
+ return "bg-neutral-100 border-neutral-200";
2009
+ }
2010
+ };
2011
+ var cleanName = (val) => val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50);
2012
+ var UniversalMembersPage = ({
2013
+ headerTitle,
2014
+ headerDescription,
2015
+ currentUserId,
2016
+ members,
2017
+ isLoading,
2018
+ currentPage,
2019
+ totalPages,
2020
+ onPageChange,
2021
+ canManage,
2022
+ canChangeRoles,
2023
+ availableRoles,
2024
+ requireNamesForInvite,
2025
+ onInviteMember,
2026
+ onRemoveMember,
2027
+ onUpdateRole
2028
+ }) => {
2029
+ const [currentView, setCurrentView] = (0, import_react43.useState)("list");
2030
+ const [selectedMember, setSelectedMember] = (0, import_react43.useState)(null);
2031
+ const [inviteEmail, setInviteEmail] = (0, import_react43.useState)("");
2032
+ const [inviteFirst, setInviteFirst] = (0, import_react43.useState)("");
2033
+ const [inviteLast, setInviteLast] = (0, import_react43.useState)("");
2034
+ const [isInviting, setIsInviting] = (0, import_react43.useState)(false);
2035
+ const [isRoleModalOpen, setIsRoleModalOpen] = (0, import_react43.useState)(false);
2036
+ const [isUpdatingRole, setIsUpdatingRole] = (0, import_react43.useState)(false);
2037
+ const [memberToDelete, setMemberToDelete] = (0, import_react43.useState)(null);
2038
+ const [isDeleting, setIsDeleting] = (0, import_react43.useState)(false);
2039
+ const dropdownRef = (0, import_react43.useRef)(null);
2040
+ (0, import_react43.useEffect)(() => {
2041
+ function handleClickOutside(event) {
2042
+ if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
2043
+ setIsRoleModalOpen(false);
2044
+ }
2045
+ }
2046
+ document.addEventListener("mousedown", handleClickOutside);
2047
+ return () => document.removeEventListener("mousedown", handleClickOutside);
2048
+ }, []);
2049
+ const handleInvite = async (e) => {
2050
+ e.preventDefault();
2051
+ if (isInviting || !canManage) return;
2052
+ setIsInviting(true);
2053
+ try {
2054
+ const res = await onInviteMember(inviteEmail, inviteFirst, inviteLast);
2055
+ if (res.success) {
2056
+ import_react_hot_toast5.default.success("Member added successfully.");
2057
+ setInviteEmail("");
2058
+ setInviteFirst("");
2059
+ setInviteLast("");
2060
+ setCurrentView("list");
2061
+ } else {
2062
+ import_react_hot_toast5.default.error(res.error || "Failed to add member.");
2063
+ }
2064
+ } catch (error) {
2065
+ import_react_hot_toast5.default.error("Service unavailable.");
2066
+ } finally {
2067
+ setIsInviting(false);
2068
+ }
2069
+ };
2070
+ const handleDelete = async () => {
2071
+ if (!memberToDelete || isDeleting || !canManage) return;
2072
+ setIsDeleting(true);
2073
+ try {
2074
+ const res = await onRemoveMember(memberToDelete);
2075
+ if (res.success) {
2076
+ import_react_hot_toast5.default.success("Member removed successfully.");
2077
+ setMemberToDelete(null);
2078
+ setCurrentView("list");
2079
+ } else {
2080
+ import_react_hot_toast5.default.error(res.error || "Failed to remove member.");
2081
+ }
2082
+ } catch (error) {
2083
+ import_react_hot_toast5.default.error("Service unavailable.");
2084
+ } finally {
2085
+ setIsDeleting(false);
2086
+ }
2087
+ };
2088
+ const handleRoleUpdate = async (newRole) => {
2089
+ if (!selectedMember || isUpdatingRole || selectedMember.role === newRole || !canChangeRoles) {
2090
+ setIsRoleModalOpen(false);
2091
+ return;
2092
+ }
2093
+ setIsRoleModalOpen(false);
2094
+ setIsUpdatingRole(true);
2095
+ try {
2096
+ const res = await onUpdateRole(selectedMember, newRole);
2097
+ if (res.success) {
2098
+ import_react_hot_toast5.default.success("Role updated successfully.");
2099
+ setSelectedMember({ ...selectedMember, role: newRole });
2100
+ } else {
2101
+ import_react_hot_toast5.default.error(res.error || "Failed to update role.");
2102
+ }
2103
+ } catch (error) {
2104
+ import_react_hot_toast5.default.error("Service unavailable.");
2105
+ } finally {
2106
+ setIsUpdatingRole(false);
2107
+ }
2108
+ };
2109
+ const goBack = () => {
2110
+ setCurrentView("list");
2111
+ setSelectedMember(null);
2112
+ setIsRoleModalOpen(false);
2113
+ };
2114
+ return /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex flex-col gap-8 animate-in max-w-3xl fade-in duration-300 p-6 rounded-2xl bg-white min-h-full" }, /* @__PURE__ */ import_react43.default.createElement(ManagedToaster, null), /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-4" }, currentView === "list" && /* @__PURE__ */ import_react43.default.createElement(import_react43.default.Fragment, null, /* @__PURE__ */ import_react43.default.createElement("div", null, /* @__PURE__ */ import_react43.default.createElement("h1", { className: "text-xl text-black mb-1 tracking-tight" }, headerTitle), /* @__PURE__ */ import_react43.default.createElement("p", { className: "text-xs text-neutral-500" }, headerDescription)), canManage && /* @__PURE__ */ import_react43.default.createElement(
2115
+ ThreeDActionButton,
2116
+ {
2117
+ onClick: () => setCurrentView("invite"),
2118
+ className: "w-fit shrink-0 gap-2"
2119
+ },
2120
+ /* @__PURE__ */ import_react43.default.createElement(import_react44.HugeiconsIcon, { icon: import_core_free_icons11.UserAdd01Icon, size: 12 }),
2121
+ "Add Member"
2122
+ )), currentView !== "list" && /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex flex-col items-start gap-3" }, /* @__PURE__ */ import_react43.default.createElement("button", { onClick: goBack, className: "text-[10px] text-neutral-400 hover:text-black tracking-[0.2em] flex items-center gap-1.5 transition-colors outline-none" }, /* @__PURE__ */ import_react43.default.createElement(import_react44.HugeiconsIcon, { icon: import_core_free_icons11.ArrowLeft01Icon, size: 12 }), " Back"), /* @__PURE__ */ import_react43.default.createElement("h1", { className: "text-lg text-black tracking-tight" }, currentView === "invite" ? "Add New Member" : "Member Profile"))), currentView === "list" && /* @__PURE__ */ import_react43.default.createElement("div", { className: "w-full overflow-hidden" }, isLoading ? /* @__PURE__ */ import_react43.default.createElement(PageSpinner2, null) : /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex flex-col min-w-0" }, /* @__PURE__ */ import_react43.default.createElement("div", { className: "divide-y divide-neutral-100" }, members.map((member) => /* @__PURE__ */ import_react43.default.createElement(
2123
+ "div",
2124
+ {
2125
+ key: member.id,
2126
+ onClick: () => {
2127
+ setSelectedMember(member);
2128
+ setCurrentView("details");
2129
+ },
2130
+ className: "flex items-center justify-between p-4 sm:p-5 hover:bg-neutral-50/50 transition-colors cursor-pointer group min-w-0"
2131
+ },
2132
+ /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex items-center gap-3 sm:gap-4 min-w-0 flex-1" }, member.displayImage && member.displayImage !== "NO_IMAGE" ? /* @__PURE__ */ import_react43.default.createElement("div", { className: "w-10 h-10 shrink-0 rounded-full overflow-hidden bg-neutral-100" }, /* @__PURE__ */ import_react43.default.createElement(
2133
+ "img",
2134
+ {
2135
+ src: member.displayImage,
2136
+ alt: member.fullName,
2137
+ className: "w-full h-full object-cover blur-sm transition-all duration-300",
2138
+ onLoad: (e) => e.currentTarget.classList.remove("blur-sm")
2139
+ }
2140
+ )) : /* @__PURE__ */ import_react43.default.createElement("div", { className: `w-10 h-10 shrink-0 rounded-full flex items-center justify-center text-black text-xs ${resolveThemeColor(member.profileColor)}` }, getInitials(member.fullName)), /* @__PURE__ */ import_react43.default.createElement("div", { className: "min-w-0 flex-1" }, /* @__PURE__ */ import_react43.default.createElement("p", { className: "text-sm text-black truncate pr-2 sm:pr-4" }, member.fullName, " ", member.userId === currentUserId && /* @__PURE__ */ import_react43.default.createElement("span", { className: "text-neutral-400 ml-1 sm:ml-2" }, "(You)")), /* @__PURE__ */ import_react43.default.createElement("p", { className: "text-xs text-neutral-500 truncate pr-2 sm:pr-4 mt-0.5" }, member.email))),
2141
+ /* @__PURE__ */ import_react43.default.createElement("div", { className: `shrink-0 pl-2 sm:pl-4 transition-opacity hidden sm:block ${canManage ? "opacity-0 group-hover:opacity-100" : "opacity-100"}` }, /* @__PURE__ */ import_react43.default.createElement("span", { className: "text-[10px] tracking-[0.2em] text-black border border-neutral-200 px-4 py-2 rounded-full bg-white whitespace-nowrap" }, canManage ? "Manage" : "View"))
2142
+ ))), /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex items-center justify-between p-4 sm:p-5" }, /* @__PURE__ */ import_react43.default.createElement("span", { className: "text-[10px] text-neutral-400 tracking-[0.2em]" }, "Page ", currentPage, " of ", totalPages), /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex items-center gap-2" }, /* @__PURE__ */ import_react43.default.createElement(
2143
+ "button",
2144
+ {
2145
+ onClick: () => onPageChange(currentPage - 1),
2146
+ disabled: currentPage === 1 || isLoading,
2147
+ className: "p-2 border border-neutral-200 rounded-full bg-white text-neutral-500 hover:text-black hover:border-black disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none"
2148
+ },
2149
+ /* @__PURE__ */ import_react43.default.createElement(import_react44.HugeiconsIcon, { icon: import_core_free_icons11.ArrowLeft01Icon, size: 14 })
2150
+ ), /* @__PURE__ */ import_react43.default.createElement(
2151
+ "button",
2152
+ {
2153
+ onClick: () => onPageChange(currentPage + 1),
2154
+ disabled: currentPage >= totalPages || isLoading,
2155
+ className: "p-2 border border-neutral-200 rounded-full bg-white text-neutral-500 hover:text-black hover:border-black disabled:opacity-30 disabled:cursor-not-allowed transition-all outline-none"
2156
+ },
2157
+ /* @__PURE__ */ import_react43.default.createElement(import_react44.HugeiconsIcon, { icon: import_core_free_icons11.ArrowRight01Icon, size: 14 })
2158
+ ))))), currentView === "details" && selectedMember && /* @__PURE__ */ import_react43.default.createElement("div", { className: "w-full max-w-2xl text-left" }, /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex flex-col gap-8" }, /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex items-center gap-5" }, selectedMember.displayImage && selectedMember.displayImage !== "NO_IMAGE" ? /* @__PURE__ */ import_react43.default.createElement("div", { className: "w-16 h-16 shrink-0 rounded-full overflow-hidden bg-neutral-100" }, /* @__PURE__ */ import_react43.default.createElement(
2159
+ "img",
2160
+ {
2161
+ src: selectedMember.displayImage,
2162
+ alt: selectedMember.fullName,
2163
+ className: "w-full h-full object-cover blur-sm transition-all duration-300",
2164
+ onLoad: (e) => e.currentTarget.classList.remove("blur-sm")
2165
+ }
2166
+ )) : /* @__PURE__ */ import_react43.default.createElement("div", { className: `w-16 h-16 shrink-0 rounded-full flex items-center justify-center text-black text-sm ${resolveThemeColor(selectedMember.profileColor)}` }, getInitials(selectedMember.fullName)), /* @__PURE__ */ import_react43.default.createElement("div", null, /* @__PURE__ */ import_react43.default.createElement("h2", { className: "text-lg text-black" }, selectedMember.fullName), /* @__PURE__ */ import_react43.default.createElement("p", { className: "text-sm text-neutral-500 mt-1" }, selectedMember.email))), /* @__PURE__ */ import_react43.default.createElement("div", { className: "grid grid-cols-2 gap-6 border-t border-neutral-200 pt-8" }, /* @__PURE__ */ import_react43.default.createElement("div", null, /* @__PURE__ */ import_react43.default.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 block mb-3" }, "Role"), canChangeRoles && selectedMember.userId !== currentUserId ? /* @__PURE__ */ import_react43.default.createElement(
2167
+ "button",
2168
+ {
2169
+ onClick: () => !isUpdatingRole && setIsRoleModalOpen(true),
2170
+ disabled: isUpdatingRole,
2171
+ className: `flex items-center gap-3 text-xs text-black pl-4 pr-3 py-2 border rounded-full transition-colors disabled:opacity-50 outline-none ${isRoleModalOpen ? "bg-neutral-50 border-neutral-300" : "bg-white border-neutral-200 hover:bg-neutral-50"}`
2172
+ },
2173
+ selectedMember.role,
2174
+ isUpdatingRole ? /* @__PURE__ */ import_react43.default.createElement(ButtonSpinner3, null) : /* @__PURE__ */ import_react43.default.createElement(import_react44.HugeiconsIcon, { icon: import_core_free_icons11.ArrowDown01Icon, size: 14, className: "text-neutral-400" })
2175
+ ) : /* @__PURE__ */ import_react43.default.createElement("span", { className: "text-xs text-black bg-neutral-50 px-4 py-2 rounded-full inline-block" }, selectedMember.role)), /* @__PURE__ */ import_react43.default.createElement("div", null, /* @__PURE__ */ import_react43.default.createElement("span", { className: "text-[10px] tracking-[0.2em] text-neutral-400 block mb-3" }, "Joined Date"), /* @__PURE__ */ import_react43.default.createElement("span", { className: "text-sm text-black" }, new Date(selectedMember.joinedAt).toLocaleDateString()))), canManage && selectedMember.userId !== currentUserId && /* @__PURE__ */ import_react43.default.createElement("div", { className: "pt-8 mt-2 border-t border-neutral-200" }, /* @__PURE__ */ import_react43.default.createElement(
2176
+ "button",
2177
+ {
2178
+ onClick: () => setMemberToDelete(selectedMember),
2179
+ className: "flex items-center gap-2 text-[11px] tracking-widest text-red-600 hover:text-red-700 transition-colors w-fit outline-none"
2180
+ },
2181
+ /* @__PURE__ */ import_react43.default.createElement(import_react44.HugeiconsIcon, { icon: import_core_free_icons11.Delete01Icon, size: 14 }),
2182
+ " Remove Member"
2183
+ )))), currentView === "invite" && canManage && /* @__PURE__ */ import_react43.default.createElement("div", { className: "w-full max-w-2xl text-left" }, /* @__PURE__ */ import_react43.default.createElement("form", { onSubmit: handleInvite, className: "space-y-8", autoComplete: "off" }, /* @__PURE__ */ import_react43.default.createElement(
2184
+ TextInput,
2185
+ {
2186
+ label: "Email Address",
2187
+ value: inviteEmail,
2188
+ onChange: (val) => setInviteEmail(val.toLowerCase()),
2189
+ disabled: isInviting,
2190
+ placeholder: "developer@acme.com"
2191
+ }
2192
+ ), requireNamesForInvite && /* @__PURE__ */ import_react43.default.createElement("div", { className: "flex flex-col sm:flex-row gap-6" }, /* @__PURE__ */ import_react43.default.createElement(
2193
+ TextInput,
2194
+ {
2195
+ label: "First Name",
2196
+ value: inviteFirst,
2197
+ onChange: (val) => setInviteFirst(cleanName(val)),
2198
+ disabled: isInviting,
2199
+ placeholder: "Jane"
2200
+ }
2201
+ ), /* @__PURE__ */ import_react43.default.createElement(
2202
+ TextInput,
2203
+ {
2204
+ label: "Last Name",
2205
+ value: inviteLast,
2206
+ onChange: (val) => setInviteLast(cleanName(val)),
2207
+ disabled: isInviting,
2208
+ placeholder: "Doe"
2209
+ }
2210
+ )), /* @__PURE__ */ import_react43.default.createElement("div", { className: "pt-8 mt-2" }, /* @__PURE__ */ import_react43.default.createElement(
2211
+ ThreeDActionButton,
2212
+ {
2213
+ type: "submit",
2214
+ disabled: isInviting || !inviteEmail || requireNamesForInvite && (!inviteFirst || !inviteLast),
2215
+ isLoading: isInviting,
2216
+ className: "min-w-40"
2217
+ },
2218
+ "Send Invitation"
2219
+ )))), isRoleModalOpen && canChangeRoles && /* @__PURE__ */ import_react43.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react43.default.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => !isUpdatingRole && setIsRoleModalOpen(false) }), /* @__PURE__ */ import_react43.default.createElement("div", { ref: dropdownRef, className: "relative w-72 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react43.default.createElement("div", { className: "p-6 text-center w-full" }, /* @__PURE__ */ import_react43.default.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Update Role")), /* @__PURE__ */ import_react43.default.createElement("div", { className: "w-full flex flex-col pl-2 pr-2" }, availableRoles.map((roleOption) => /* @__PURE__ */ import_react43.default.createElement(
2220
+ "button",
2221
+ {
2222
+ key: roleOption,
2223
+ onClick: () => handleRoleUpdate(roleOption),
2224
+ disabled: isUpdatingRole,
2225
+ className: `text-left px-4 py-3 text-[12px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${selectedMember?.role === roleOption ? "bg-neutral-100 text-black" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
2226
+ },
2227
+ /* @__PURE__ */ import_react43.default.createElement("span", { className: "truncate pr-2" }, roleOption),
2228
+ selectedMember?.role === roleOption && /* @__PURE__ */ import_react43.default.createElement("div", { className: "w-1.5 h-1.5 rounded-full shrink-0 bg-black" })
2229
+ ))), /* @__PURE__ */ import_react43.default.createElement("div", { className: "w-full flex" }, /* @__PURE__ */ import_react43.default.createElement(
2230
+ "button",
2231
+ {
2232
+ onClick: () => setIsRoleModalOpen(false),
2233
+ disabled: isUpdatingRole,
2234
+ className: "w-full py-2.5 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors disabled:opacity-50 outline-none"
2235
+ },
2236
+ "Cancel"
2237
+ )))), memberToDelete && canManage && /* @__PURE__ */ import_react43.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react43.default.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => !isDeleting && setMemberToDelete(null) }), /* @__PURE__ */ import_react43.default.createElement("div", { className: "relative w-72 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react43.default.createElement("div", { className: "p-6 text-center w-full" }, /* @__PURE__ */ import_react43.default.createElement("h3", { className: "text-[14px] text-black tracking-tight mb-1" }, "Remove Member"), /* @__PURE__ */ import_react43.default.createElement("p", { className: "text-[12px] text-neutral-500 leading-snug mt-2" }, "Are you sure you want to remove this member? They will lose access instantly.")), /* @__PURE__ */ import_react43.default.createElement("div", { className: "w-full flex" }, /* @__PURE__ */ import_react43.default.createElement("button", { onClick: () => setMemberToDelete(null), disabled: isDeleting, className: "flex-1 py-2 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors disabled:opacity-50 outline-none" }, "Cancel"), /* @__PURE__ */ import_react43.default.createElement("button", { onClick: handleDelete, disabled: isDeleting, className: "flex-1 py-2 text-[13px] text-red-600 hover:bg-neutral-50 transition-colors disabled:opacity-50 flex justify-center outline-none" }, isDeleting ? /* @__PURE__ */ import_react43.default.createElement(ButtonSpinner3, null) : "Remove")))));
2238
+ };
2239
+
2240
+ // src/components/UniversalProfileSettings.tsx
2241
+ var import_react45 = __toESM(require("react"));
2242
+ var import_react_hot_toast6 = __toESM(require("react-hot-toast"));
2243
+ var import_react46 = require("@hugeicons/react");
2244
+ var import_core_free_icons12 = require("@hugeicons/core-free-icons");
2245
+ var UniversalProfileSettings = ({
2246
+ initialFirstName,
2247
+ initialLastName,
2248
+ email,
2249
+ initialProfileColor,
2250
+ accountStatus = "GOOD",
2251
+ memberSince,
2252
+ isReadOnly = false,
2253
+ themeColors,
2254
+ onSaveProfile
2255
+ }) => {
2256
+ const [firstName, setFirstName] = (0, import_react45.useState)(initialFirstName);
2257
+ const [lastName, setLastName] = (0, import_react45.useState)(initialLastName);
2258
+ const [profileColor, setProfileColor] = (0, import_react45.useState)(initialProfileColor);
2259
+ const [isSubmitting, setIsSubmitting] = (0, import_react45.useState)(false);
2260
+ const [isColorModalOpen, setIsColorModalOpen] = (0, import_react45.useState)(false);
2261
+ (0, import_react45.useEffect)(() => {
2262
+ setFirstName(initialFirstName || "");
2263
+ setLastName(initialLastName || "");
2264
+ setProfileColor(initialProfileColor || "NONE");
2265
+ }, [initialFirstName, initialLastName, initialProfileColor]);
2266
+ const handleFirstNameChange = (val) => {
2267
+ setFirstName(val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50));
2268
+ };
2269
+ const handleLastNameChange = (val) => {
2270
+ setLastName(val.replace(/[^a-zA-Z\s-]/g, "").substring(0, 50));
2271
+ };
2272
+ const handleSave = async (e) => {
2273
+ e.preventDefault();
2274
+ if (isSubmitting || isReadOnly) return;
2275
+ setIsSubmitting(true);
2276
+ try {
2277
+ const res = await onSaveProfile({ firstName, lastName, profileColor });
2278
+ if (res.success) {
2279
+ import_react_hot_toast6.default.success("Profile updated successfully.");
2280
+ setTimeout(() => window.location.reload(), 1e3);
2281
+ } else {
2282
+ import_react_hot_toast6.default.error(res.error || "Failed to update profile.");
2283
+ setIsSubmitting(false);
2284
+ }
2285
+ } catch (error) {
2286
+ import_react_hot_toast6.default.error("Service unavailable. Try again later.");
2287
+ setIsSubmitting(false);
2288
+ }
2289
+ };
2290
+ const hasChanges = firstName !== initialFirstName || lastName !== initialLastName || profileColor !== initialProfileColor;
2291
+ const isSaveDisabled = isSubmitting || isReadOnly || !hasChanges || firstName.trim().length === 0 || lastName.trim().length === 0;
2292
+ const selectedColorDef = themeColors.find((c) => c.id === profileColor) || themeColors[0] || { label: "Default", bgClass: "bg-neutral-100", borderClass: "border-neutral-200" };
2293
+ return /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex flex-col max-w-3xl rounded-2xl p-6 bg-white gap-8 animate-in fade-in duration-300 min-h-full" }, /* @__PURE__ */ import_react45.default.createElement(ManagedToaster, null), /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-start justify-between gap-3 sm:gap-4" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react45.default.createElement("h1", { className: "text-xl text-black mb-1 truncate tracking-tight" }, "Personal Settings"), /* @__PURE__ */ import_react45.default.createElement("p", { className: "text-xs text-neutral-500 truncate" }, "Manage your personal account profile.")), isReadOnly && /* @__PURE__ */ import_react45.default.createElement("span", { className: "px-3 py-1 bg-neutral-50 text-neutral-500 rounded-full text-[10px] tracking-[0.2em] shrink-0 w-fit" }, "Read Only Access")), /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-full max-w-2xl" }, /* @__PURE__ */ import_react45.default.createElement("form", { className: "flex flex-col gap-8", onSubmit: handleSave, autoComplete: "off" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex flex-col sm:flex-row gap-6" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react45.default.createElement(
2294
+ TextInput,
2295
+ {
2296
+ label: "First Name",
2297
+ value: firstName,
2298
+ onChange: handleFirstNameChange,
2299
+ disabled: isReadOnly || isSubmitting,
2300
+ placeholder: "System"
2301
+ }
2302
+ )), /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex-1 min-w-0" }, /* @__PURE__ */ import_react45.default.createElement(
2303
+ TextInput,
2304
+ {
2305
+ label: "Last Name",
2306
+ value: lastName,
2307
+ onChange: handleLastNameChange,
2308
+ disabled: isReadOnly || isSubmitting,
2309
+ placeholder: "Admin"
2310
+ }
2311
+ ))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "space-y-2 min-w-0" }, /* @__PURE__ */ import_react45.default.createElement(
2312
+ TextInput,
2313
+ {
2314
+ label: "Email ID",
2315
+ value: email,
2316
+ onChange: () => {
2317
+ },
2318
+ disabled: true
2319
+ }
2320
+ ), /* @__PURE__ */ import_react45.default.createElement("p", { className: "text-[10px] text-neutral-400 mt-1 truncate" }, "To change your email address, please contact support.")), /* @__PURE__ */ import_react45.default.createElement("div", { className: "space-y-2 min-w-0" }, /* @__PURE__ */ import_react45.default.createElement("label", { className: "text-[10px] text-neutral-400 tracking-[0.2em] truncate block uppercase" }, "Profile Color"), /* @__PURE__ */ import_react45.default.createElement(
2321
+ "button",
2322
+ {
2323
+ type: "button",
2324
+ onClick: () => !isReadOnly && setIsColorModalOpen(true),
2325
+ disabled: isReadOnly || isSubmitting,
2326
+ className: "w-full flex items-center justify-between px-2 py-3 text-sm bg-transparent border-b border-neutral-200 text-black transition-all outline-none focus:border-black disabled:opacity-50 disabled:cursor-not-allowed text-left"
2327
+ },
2328
+ /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: `w-4 h-4 rounded-full border ${selectedColorDef.bgClass} ${selectedColorDef.borderClass}` }), /* @__PURE__ */ import_react45.default.createElement("span", null, selectedColorDef.label)),
2329
+ /* @__PURE__ */ import_react45.default.createElement(import_react46.HugeiconsIcon, { icon: import_core_free_icons12.ArrowDown01Icon, size: 14, className: "text-neutral-400 shrink-0" })
2330
+ )), /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between pt-8 mt-2 gap-6 sm:gap-4 border-t border-neutral-100" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center gap-6 min-w-0" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "text-[10px] text-neutral-400 tracking-[0.2em] block truncate uppercase" }, "Account Status"), /* @__PURE__ */ import_react45.default.createElement("span", { className: "text-xs text-black block truncate" }, accountStatus)), /* @__PURE__ */ import_react45.default.createElement("div", { className: "min-w-0" }, /* @__PURE__ */ import_react45.default.createElement("span", { className: "text-[10px] text-neutral-400 tracking-[0.2em] block truncate uppercase" }, "Member Since"), /* @__PURE__ */ import_react45.default.createElement("span", { className: "text-xs text-black block truncate" }, memberSince ? new Date(memberSince).toLocaleDateString("en-US", { month: "long", day: "numeric", year: "numeric" }) : "N/A"))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex flex-col-reverse sm:flex-row items-center gap-3 sm:gap-4 w-full sm:w-auto shrink-0" }, hasChanges && !isSubmitting && !isReadOnly && /* @__PURE__ */ import_react45.default.createElement(
2331
+ "button",
2332
+ {
2333
+ type: "button",
2334
+ onClick: () => {
2335
+ setFirstName(initialFirstName);
2336
+ setLastName(initialLastName);
2337
+ setProfileColor(initialProfileColor);
2338
+ },
2339
+ className: "text-[11px] tracking-widest text-neutral-500 hover:text-black transition-colors w-full sm:w-auto py-2 sm:py-0 outline-none"
2340
+ },
2341
+ "Cancel"
2342
+ ), /* @__PURE__ */ import_react45.default.createElement(
2343
+ ThreeDActionButton,
2344
+ {
2345
+ type: "submit",
2346
+ disabled: isSaveDisabled,
2347
+ isLoading: isSubmitting,
2348
+ className: "min-w-32 w-full sm:w-auto"
2349
+ },
2350
+ "Save Changes"
2351
+ ))))), isColorModalOpen && !isReadOnly && /* @__PURE__ */ import_react45.default.createElement("div", { className: "fixed inset-0 z-110 flex items-center justify-center p-4" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "absolute inset-0 bg-black/30", onClick: () => setIsColorModalOpen(false) }), /* @__PURE__ */ import_react45.default.createElement("div", { className: "relative w-72 bg-white shadow-2xl rounded-2xl flex flex-col items-center overflow-hidden animate-in zoom-in-95 duration-200" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: "p-6 text-center w-full" }, /* @__PURE__ */ import_react45.default.createElement("h3", { className: "text-[14px] text-black tracking-tight" }, "Pick Profile Color")), /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-full flex flex-col pl-2 pr-2 pb-2" }, themeColors.map((colorOption) => /* @__PURE__ */ import_react45.default.createElement(
2352
+ "button",
2353
+ {
2354
+ type: "button",
2355
+ key: colorOption.id,
2356
+ onClick: () => {
2357
+ setProfileColor(colorOption.id);
2358
+ setIsColorModalOpen(false);
2359
+ },
2360
+ className: `text-left px-4 py-3 text-[12px] tracking-wide transition-colors rounded-full flex items-center justify-between outline-none ${profileColor === colorOption.id ? "bg-neutral-100 text-black" : "text-neutral-500 hover:bg-neutral-50 hover:text-black"}`
2361
+ },
2362
+ /* @__PURE__ */ import_react45.default.createElement("div", { className: "flex items-center gap-3" }, /* @__PURE__ */ import_react45.default.createElement("div", { className: `w-3.5 h-3.5 rounded-full border ${colorOption.bgClass} ${colorOption.borderClass}` }), /* @__PURE__ */ import_react45.default.createElement("span", { className: "truncate pr-2" }, colorOption.label)),
2363
+ profileColor === colorOption.id && /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-1.5 h-1.5 rounded-full shrink-0 bg-black" })
2364
+ ))), /* @__PURE__ */ import_react45.default.createElement("div", { className: "w-full flex" }, /* @__PURE__ */ import_react45.default.createElement(
2365
+ "button",
2366
+ {
2367
+ type: "button",
2368
+ onClick: () => setIsColorModalOpen(false),
2369
+ className: "w-full py-2.5 text-[13px] text-neutral-600 hover:bg-neutral-50 transition-colors outline-none"
2370
+ },
2371
+ "Cancel"
2372
+ )))));
2373
+ };
1489
2374
  // Annotate the CommonJS export names for ESM import in node:
1490
2375
  0 && (module.exports = {
1491
2376
  AITranscriptionFeature,
@@ -1512,5 +2397,11 @@ var GifFeatureCard = ({
1512
2397
  TextInput,
1513
2398
  ThreeDActionButton,
1514
2399
  ThreeDButton,
2400
+ UniversalHeader,
2401
+ UniversalIdentityPage,
2402
+ UniversalMembersPage,
2403
+ UniversalOrganizationPage,
2404
+ UniversalProfileSettings,
2405
+ UniversalSidebar,
1515
2406
  ZairusAuth
1516
2407
  });