@cedros/login-react 0.0.29 → 0.0.30

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.
Files changed (175) hide show
  1. package/README.md +2 -0
  2. package/dist/{AdminDepositList-CyT4VBH8.js → AdminDepositList-BUm_ZcAW.js} +1 -1
  3. package/dist/{AdminDepositList-CyT4VBH8.js.map → AdminDepositList-BUm_ZcAW.js.map} +1 -1
  4. package/dist/{AdminDepositList-b2AXtLg0.cjs → AdminDepositList-B_z6x3j5.cjs} +1 -1
  5. package/dist/{AdminDepositList-b2AXtLg0.cjs.map → AdminDepositList-B_z6x3j5.cjs.map} +1 -1
  6. package/dist/{AdminWithdrawalHistory-DL9zbu2b.cjs → AdminWithdrawalHistory-B2EY2ZmH.cjs} +1 -1
  7. package/dist/{AdminWithdrawalHistory-DL9zbu2b.cjs.map → AdminWithdrawalHistory-B2EY2ZmH.cjs.map} +1 -1
  8. package/dist/{AdminWithdrawalHistory-Cud-yuWy.js → AdminWithdrawalHistory-C76bkbjX.js} +1 -1
  9. package/dist/{AdminWithdrawalHistory-Cud-yuWy.js.map → AdminWithdrawalHistory-C76bkbjX.js.map} +1 -1
  10. package/dist/{AuthenticationSettings-D6GvSw3g.cjs → AuthenticationSettings-C-aYDXNH.cjs} +1 -1
  11. package/dist/{AuthenticationSettings-D6GvSw3g.cjs.map → AuthenticationSettings-C-aYDXNH.cjs.map} +1 -1
  12. package/dist/AuthenticationSettings-CoTic-d_.cjs +1 -0
  13. package/dist/AuthenticationSettings-CoTic-d_.cjs.map +1 -0
  14. package/dist/{AuthenticationSettings-rb4Fksw5.js → AuthenticationSettings-CsPbxwP7.js} +1 -1
  15. package/dist/{AuthenticationSettings-rb4Fksw5.js.map → AuthenticationSettings-CsPbxwP7.js.map} +1 -1
  16. package/dist/AuthenticationSettings-DIVk0OP8.js +712 -0
  17. package/dist/AuthenticationSettings-DIVk0OP8.js.map +1 -0
  18. package/dist/AutosaveStatus-DGNI4lXn.cjs +1 -0
  19. package/dist/AutosaveStatus-DGNI4lXn.cjs.map +1 -0
  20. package/dist/{AutosaveStatus-vkJxtuEw.js → AutosaveStatus-f-jw25Ay.js} +141 -93
  21. package/dist/AutosaveStatus-f-jw25Ay.js.map +1 -0
  22. package/dist/{CreditSystemSettings-ChA_lbef.cjs → CreditSystemSettings-BNkvsgsk.cjs} +1 -1
  23. package/dist/{CreditSystemSettings-ChA_lbef.cjs.map → CreditSystemSettings-BNkvsgsk.cjs.map} +1 -1
  24. package/dist/{CreditSystemSettings-DsRipb2R.js → CreditSystemSettings-C6ed3yp7.js} +1 -1
  25. package/dist/{CreditSystemSettings-DsRipb2R.js.map → CreditSystemSettings-C6ed3yp7.js.map} +1 -1
  26. package/dist/{CreditSystemSettings-r3gnGjiU.cjs → CreditSystemSettings-DM9ep1TF.cjs} +1 -1
  27. package/dist/{CreditSystemSettings-r3gnGjiU.cjs.map → CreditSystemSettings-DM9ep1TF.cjs.map} +1 -1
  28. package/dist/{CreditSystemSettings-a31pqSYS.js → CreditSystemSettings-uinhzoha.js} +1 -1
  29. package/dist/{CreditSystemSettings-a31pqSYS.js.map → CreditSystemSettings-uinhzoha.js.map} +1 -1
  30. package/dist/{DepositsSection-DD9MKUFt.js → DepositsSection-Bb4ISzvE.js} +1 -1
  31. package/dist/{DepositsSection-DD9MKUFt.js.map → DepositsSection-Bb4ISzvE.js.map} +1 -1
  32. package/dist/{DepositsSection-BkKUS4vk.cjs → DepositsSection-uQUdGeVb.cjs} +1 -1
  33. package/dist/{DepositsSection-BkKUS4vk.cjs.map → DepositsSection-uQUdGeVb.cjs.map} +1 -1
  34. package/dist/EmailRegisterForm-B_TiJkD6.cjs +1 -0
  35. package/dist/EmailRegisterForm-B_TiJkD6.cjs.map +1 -0
  36. package/dist/EmailRegisterForm-CCEuQA-w.js +773 -0
  37. package/dist/EmailRegisterForm-CCEuQA-w.js.map +1 -0
  38. package/dist/{EmailSettings-BVJ4vz0Y.js → EmailSettings-BAuQtEfM.js} +1 -1
  39. package/dist/{EmailSettings-BVJ4vz0Y.js.map → EmailSettings-BAuQtEfM.js.map} +1 -1
  40. package/dist/{EmailSettings-Dg2SAiHj.cjs → EmailSettings-BC0f1PCI.cjs} +1 -1
  41. package/dist/{EmailSettings-Dg2SAiHj.cjs.map → EmailSettings-BC0f1PCI.cjs.map} +1 -1
  42. package/dist/{EmailSettings-CM5l8qqK.cjs → EmailSettings-BF5EiPl9.cjs} +1 -1
  43. package/dist/{EmailSettings-CM5l8qqK.cjs.map → EmailSettings-BF5EiPl9.cjs.map} +1 -1
  44. package/dist/{EmailSettings-xtVl4kXD.js → EmailSettings-BKuXy8sc.js} +1 -1
  45. package/dist/{EmailSettings-xtVl4kXD.js.map → EmailSettings-BKuXy8sc.js.map} +1 -1
  46. package/dist/{EmbeddedWalletSettings-Bmx8x21f.cjs → EmbeddedWalletSettings-BRjt2PAj.cjs} +1 -1
  47. package/dist/{EmbeddedWalletSettings-Bmx8x21f.cjs.map → EmbeddedWalletSettings-BRjt2PAj.cjs.map} +1 -1
  48. package/dist/{EmbeddedWalletSettings-BuDgqv-K.js → EmbeddedWalletSettings-C27X9He2.js} +1 -1
  49. package/dist/{EmbeddedWalletSettings-BuDgqv-K.js.map → EmbeddedWalletSettings-C27X9He2.js.map} +1 -1
  50. package/dist/{EmbeddedWalletSettings-BXN9VbNJ.cjs → EmbeddedWalletSettings-CJY39UZN.cjs} +1 -1
  51. package/dist/{EmbeddedWalletSettings-BXN9VbNJ.cjs.map → EmbeddedWalletSettings-CJY39UZN.cjs.map} +1 -1
  52. package/dist/{EmbeddedWalletSettings-DY5iJhS0.js → EmbeddedWalletSettings-Dmi-EQ7W.js} +1 -1
  53. package/dist/{EmbeddedWalletSettings-DY5iJhS0.js.map → EmbeddedWalletSettings-Dmi-EQ7W.js.map} +1 -1
  54. package/dist/GoogleLoginButton-CjBO3Rf1.cjs +1 -0
  55. package/dist/GoogleLoginButton-CjBO3Rf1.cjs.map +1 -0
  56. package/dist/{GoogleLoginButton-B6qnNMZp.js → GoogleLoginButton-DEbiQngr.js} +51 -51
  57. package/dist/GoogleLoginButton-DEbiQngr.js.map +1 -0
  58. package/dist/LoadingSpinner-6vml-zwr.js.map +1 -1
  59. package/dist/LoadingSpinner-d6sSxgQN.cjs.map +1 -1
  60. package/dist/{PermissionsSection-BPbE-hNx.cjs → PermissionsSection-DEMVp7X3.cjs} +1 -1
  61. package/dist/PermissionsSection-DEMVp7X3.cjs.map +1 -0
  62. package/dist/{PermissionsSection-CighC1p6.js → PermissionsSection-DNzOL1xW.js} +27 -25
  63. package/dist/PermissionsSection-DNzOL1xW.js.map +1 -0
  64. package/dist/{ServerSettings-BAstMKHS.js → ServerSettings-BT9weFPz.js} +1 -1
  65. package/dist/{ServerSettings-BAstMKHS.js.map → ServerSettings-BT9weFPz.js.map} +1 -1
  66. package/dist/{ServerSettings-LIIP5TPz.cjs → ServerSettings-CKfiLfXi.cjs} +1 -1
  67. package/dist/{ServerSettings-LIIP5TPz.cjs.map → ServerSettings-CKfiLfXi.cjs.map} +1 -1
  68. package/dist/{ServerSettings-9Q091f3o.js → ServerSettings-CZfBdMxG.js} +1 -1
  69. package/dist/{ServerSettings-9Q091f3o.js.map → ServerSettings-CZfBdMxG.js.map} +1 -1
  70. package/dist/{ServerSettings-PH7T8JKI.cjs → ServerSettings-rHrVN8O8.cjs} +1 -1
  71. package/dist/{ServerSettings-PH7T8JKI.cjs.map → ServerSettings-rHrVN8O8.cjs.map} +1 -1
  72. package/dist/SolanaLoginButton-DAV3r4oB.cjs +1 -0
  73. package/dist/SolanaLoginButton-DAV3r4oB.cjs.map +1 -0
  74. package/dist/{mobileWalletAdapter-Cm_AUXhg.js → SolanaLoginButton-DFOoLqoj.js} +75 -74
  75. package/dist/SolanaLoginButton-DFOoLqoj.js.map +1 -0
  76. package/dist/{TeamSection-BIECkp7g.js → TeamSection-CoMXyFtz.js} +2 -2
  77. package/dist/{TeamSection-BIECkp7g.js.map → TeamSection-CoMXyFtz.js.map} +1 -1
  78. package/dist/{TeamSection-BOH9pv_E.cjs → TeamSection-DopbZClq.cjs} +1 -1
  79. package/dist/{TeamSection-BOH9pv_E.cjs.map → TeamSection-DopbZClq.cjs.map} +1 -1
  80. package/dist/{UsersSection-t-zm0jZW.js → UsersSection--PAE1XRh.js} +1 -1
  81. package/dist/{UsersSection-t-zm0jZW.js.map → UsersSection--PAE1XRh.js.map} +1 -1
  82. package/dist/{UsersSection-e6q7FHzx.cjs → UsersSection-C7aRNkK2.cjs} +1 -1
  83. package/dist/{UsersSection-e6q7FHzx.cjs.map → UsersSection-C7aRNkK2.cjs.map} +1 -1
  84. package/dist/{WebhookSettings-D0F8ESlB.js → WebhookSettings-Bgld6D_T.js} +1 -1
  85. package/dist/{WebhookSettings-D0F8ESlB.js.map → WebhookSettings-Bgld6D_T.js.map} +1 -1
  86. package/dist/{WebhookSettings-2p9abGm5.cjs → WebhookSettings-DXjnq-c7.cjs} +1 -1
  87. package/dist/{WebhookSettings-2p9abGm5.cjs.map → WebhookSettings-DXjnq-c7.cjs.map} +1 -1
  88. package/dist/{WebhookSettings-CdFM7_V-.cjs → WebhookSettings-DnLk97Mr.cjs} +1 -1
  89. package/dist/{WebhookSettings-CdFM7_V-.cjs.map → WebhookSettings-DnLk97Mr.cjs.map} +1 -1
  90. package/dist/{WebhookSettings-CXMBju7N.js → WebhookSettings-ufiGTmbG.js} +1 -1
  91. package/dist/{WebhookSettings-CXMBju7N.js.map → WebhookSettings-ufiGTmbG.js.map} +1 -1
  92. package/dist/{WithdrawalsSection-yRDTVFsb.js → WithdrawalsSection-BN-FjTEV.js} +1 -1
  93. package/dist/{WithdrawalsSection-yRDTVFsb.js.map → WithdrawalsSection-BN-FjTEV.js.map} +1 -1
  94. package/dist/{WithdrawalsSection-sljIyeaz.cjs → WithdrawalsSection-BhuCwFat.cjs} +1 -1
  95. package/dist/{WithdrawalsSection-sljIyeaz.cjs.map → WithdrawalsSection-BhuCwFat.cjs.map} +1 -1
  96. package/dist/admin-only.cjs +1 -1
  97. package/dist/admin-only.js +1 -1
  98. package/dist/email-only.cjs +1 -1
  99. package/dist/email-only.d.ts +17 -1
  100. package/dist/email-only.js +3 -3
  101. package/dist/google-only.cjs +1 -1
  102. package/dist/google-only.d.ts +16 -0
  103. package/dist/google-only.js +3 -3
  104. package/dist/index.cjs +12 -12
  105. package/dist/index.cjs.map +1 -1
  106. package/dist/index.d.ts +246 -10
  107. package/dist/index.js +3384 -2508
  108. package/dist/index.js.map +1 -1
  109. package/dist/login-react.css +1 -1
  110. package/dist/{plugin-DbkijwEV.js → plugin-BbExid4E.js} +1 -1
  111. package/dist/{plugin-DbkijwEV.js.map → plugin-BbExid4E.js.map} +1 -1
  112. package/dist/{plugin-PU2vAozn.cjs → plugin-Xca67fp7.cjs} +1 -1
  113. package/dist/{plugin-PU2vAozn.cjs.map → plugin-Xca67fp7.cjs.map} +1 -1
  114. package/dist/{shamir-CiBczzDN.cjs → shamir-DBpHm7WN.cjs} +1 -1
  115. package/dist/{shamir-CiBczzDN.cjs.map → shamir-DBpHm7WN.cjs.map} +1 -1
  116. package/dist/{shamir-OAB2zD9Y.js → shamir-R8ddesFt.js} +1 -1
  117. package/dist/{shamir-OAB2zD9Y.js.map → shamir-R8ddesFt.js.map} +1 -1
  118. package/dist/{silentWalletEnroll-FqXS7Rvh.js → silentWalletEnroll-Dp1GTeNr.js} +3 -3
  119. package/dist/{silentWalletEnroll-FqXS7Rvh.js.map → silentWalletEnroll-Dp1GTeNr.js.map} +1 -1
  120. package/dist/{silentWalletEnroll-wnkcB9HP.cjs → silentWalletEnroll-HPvsbd2J.cjs} +1 -1
  121. package/dist/{silentWalletEnroll-wnkcB9HP.cjs.map → silentWalletEnroll-HPvsbd2J.cjs.map} +1 -1
  122. package/dist/solana-only.cjs +1 -1
  123. package/dist/solana-only.d.ts +16 -0
  124. package/dist/solana-only.js +3 -3
  125. package/dist/{useAdminDeposits-BTSyeAfg.js → useAdminDeposits-C76B2Q_8.js} +1 -1
  126. package/dist/{useAdminDeposits-BTSyeAfg.js.map → useAdminDeposits-C76B2Q_8.js.map} +1 -1
  127. package/dist/{useAdminDeposits-BkkCwHWp.cjs → useAdminDeposits-CpLd68oP.cjs} +1 -1
  128. package/dist/{useAdminDeposits-BkkCwHWp.cjs.map → useAdminDeposits-CpLd68oP.cjs.map} +1 -1
  129. package/dist/{useAuth-m5Hf89v8.js → useAuth-CVLv2oKA.js} +547 -545
  130. package/dist/useAuth-CVLv2oKA.js.map +1 -0
  131. package/dist/useAuth-XZaciuLg.cjs +1 -0
  132. package/dist/useAuth-XZaciuLg.cjs.map +1 -0
  133. package/dist/useCedrosLogin-CFfID-0i.js +228 -0
  134. package/dist/useCedrosLogin-CFfID-0i.js.map +1 -0
  135. package/dist/useCedrosLogin-DtJorrE7.cjs +1 -0
  136. package/dist/useCedrosLogin-DtJorrE7.cjs.map +1 -0
  137. package/dist/{useOrgs-C3pzMA9h.js → useOrgs-C90KT9KP.js} +1 -1
  138. package/dist/{useOrgs-C3pzMA9h.js.map → useOrgs-C90KT9KP.js.map} +1 -1
  139. package/dist/{useOrgs-DDVRCaVi.cjs → useOrgs-CNqfn-fk.cjs} +1 -1
  140. package/dist/{useOrgs-DDVRCaVi.cjs.map → useOrgs-CNqfn-fk.cjs.map} +1 -1
  141. package/dist/{useSystemSettings-DRrreszl.cjs → useSystemSettings-B2jY51ob.cjs} +1 -1
  142. package/dist/{useSystemSettings-DRrreszl.cjs.map → useSystemSettings-B2jY51ob.cjs.map} +1 -1
  143. package/dist/{useSystemSettings-DBlAMjFi.js → useSystemSettings-rgskaDqP.js} +1 -1
  144. package/dist/{useSystemSettings-DBlAMjFi.js.map → useSystemSettings-rgskaDqP.js.map} +1 -1
  145. package/dist/{useUsersStatsSummary-NjEFvWuz.js → useUsersStatsSummary-5DJwzntC.js} +2 -2
  146. package/dist/{useUsersStatsSummary-NjEFvWuz.js.map → useUsersStatsSummary-5DJwzntC.js.map} +1 -1
  147. package/dist/{useUsersStatsSummary-8qY7iP4G.cjs → useUsersStatsSummary-DgKaUIfs.cjs} +1 -1
  148. package/dist/{useUsersStatsSummary-8qY7iP4G.cjs.map → useUsersStatsSummary-DgKaUIfs.cjs.map} +1 -1
  149. package/package.json +1 -1
  150. package/dist/AuthenticationSettings-C9f5MKgj.cjs +0 -1
  151. package/dist/AuthenticationSettings-C9f5MKgj.cjs.map +0 -1
  152. package/dist/AuthenticationSettings-DC64o_J6.js +0 -525
  153. package/dist/AuthenticationSettings-DC64o_J6.js.map +0 -1
  154. package/dist/AutosaveStatus-BFj5GIab.cjs +0 -1
  155. package/dist/AutosaveStatus-BFj5GIab.cjs.map +0 -1
  156. package/dist/AutosaveStatus-vkJxtuEw.js.map +0 -1
  157. package/dist/EmailRegisterForm-B1DB-bqe.cjs +0 -1
  158. package/dist/EmailRegisterForm-B1DB-bqe.cjs.map +0 -1
  159. package/dist/EmailRegisterForm-BAX_uBIt.js +0 -927
  160. package/dist/EmailRegisterForm-BAX_uBIt.js.map +0 -1
  161. package/dist/GoogleLoginButton-B6qnNMZp.js.map +0 -1
  162. package/dist/GoogleLoginButton-D7CoMXLq.cjs +0 -1
  163. package/dist/GoogleLoginButton-D7CoMXLq.cjs.map +0 -1
  164. package/dist/PermissionsSection-BPbE-hNx.cjs.map +0 -1
  165. package/dist/PermissionsSection-CighC1p6.js.map +0 -1
  166. package/dist/mobileWalletAdapter-B6ELaZp1.cjs +0 -1
  167. package/dist/mobileWalletAdapter-B6ELaZp1.cjs.map +0 -1
  168. package/dist/mobileWalletAdapter-Cm_AUXhg.js.map +0 -1
  169. package/dist/useAuth-X6Ds6WW4.cjs +0 -1
  170. package/dist/useAuth-X6Ds6WW4.cjs.map +0 -1
  171. package/dist/useAuth-m5Hf89v8.js.map +0 -1
  172. package/dist/useCedrosLogin-C9MrcZvh.cjs +0 -1
  173. package/dist/useCedrosLogin-C9MrcZvh.cjs.map +0 -1
  174. package/dist/useCedrosLogin-_94MmGGq.js +0 -216
  175. package/dist/useCedrosLogin-_94MmGGq.js.map +0 -1
@@ -1,6 +1,6 @@
1
1
  import { jsxs as k, jsx as g } from "react/jsx-runtime";
2
- import { useState as m, useRef as w, useMemo as y, useEffect as C, useCallback as R } from "react";
3
- import { u as v, A as G, h as _ } from "./useCedrosLogin-_94MmGGq.js";
2
+ import { useState as p, useRef as I, useMemo as S, useEffect as C, useCallback as R } from "react";
3
+ import { u as v, A as G, h as _ } from "./useCedrosLogin-CFfID-0i.js";
4
4
  import { L as z } from "./LoadingSpinner-6vml-zwr.js";
5
5
  const O = {
6
6
  loading: !1,
@@ -19,14 +19,14 @@ const O = {
19
19
  });
20
20
  return;
21
21
  }
22
- const s = document.createElement("script");
23
- s.src = "https://accounts.google.com/gsi/client", s.async = !0, s.defer = !0, s.id = "google-gsi-script", s.onload = () => {
22
+ const o = document.createElement("script");
23
+ o.src = "https://accounts.google.com/gsi/client", o.async = !0, o.defer = !0, o.id = "google-gsi-script", o.onload = () => {
24
24
  this.loaded = !0, this.loading = !1, this.callbacks.forEach((t) => t.resolve()), this.callbacks = [];
25
- }, s.onerror = () => {
26
- this.loading = !1, s.remove();
25
+ }, o.onerror = () => {
26
+ this.loading = !1, o.remove();
27
27
  const t = new Error("Failed to load Google Sign-In script");
28
28
  this.callbacks.forEach((f) => f.reject(t)), this.callbacks = [];
29
- }, document.head.appendChild(s);
29
+ }, document.head.appendChild(o);
30
30
  }));
31
31
  },
32
32
  /**
@@ -37,8 +37,8 @@ const O = {
37
37
  this.loading = !1, this.loaded = !1, this.error = null, this.callbacks = [];
38
38
  }
39
39
  };
40
- function M() {
41
- const { config: e, _internal: c } = v(), [d, s] = m(!1), [t, f] = m(!1), [E, n] = m(null), [I, h] = m(null), a = w(null), b = w(e), u = y(
40
+ function P() {
41
+ const { config: e, _internal: c } = v(), [d, o] = p(!1), [t, f] = p(!1), [E, n] = p(null), [b, h] = p(null), a = I(null), w = I(e), u = S(
42
42
  () => new G({
43
43
  baseUrl: e.serverUrl,
44
44
  timeoutMs: e.requestTimeout,
@@ -47,20 +47,20 @@ function M() {
47
47
  [e.serverUrl, e.requestTimeout, e.retryAttempts]
48
48
  );
49
49
  C(() => {
50
- b.current = e;
50
+ w.current = e;
51
51
  }, [e]);
52
- const p = R(
53
- async (o) => {
52
+ const m = R(
53
+ async (s) => {
54
54
  const i = a.current;
55
55
  if (i)
56
56
  try {
57
57
  const r = await u.post("/google", {
58
- idToken: o.credential
58
+ idToken: s.credential
59
59
  });
60
- b.current.callbacks?.onLoginSuccess?.(r.user, "google"), c?.handleLoginSuccess(r.user, r.tokens), s(!1), i.resolve(r);
60
+ w.current.callbacks?.onLoginSuccess?.(r.user, "google"), c?.handleLoginSuccess(r.user, r.tokens), o(!1), i.resolve(r);
61
61
  } catch (r) {
62
- const l = _(r, "Google sign-in failed");
63
- l.code === "ACCOUNT_LINK_REQUIRED" && h(o.credential), n(l), s(!1), i.reject(l);
62
+ const l = _(r, "Unable to sign in with Google. Please try again.");
63
+ l.code === "ACCOUNT_LINK_REQUIRED" && h(s.credential), n(l), o(!1), i.reject(l);
64
64
  } finally {
65
65
  a.current = null;
66
66
  }
@@ -70,79 +70,79 @@ function M() {
70
70
  C(() => {
71
71
  if (!e.googleClientId)
72
72
  return;
73
- let o = !0;
73
+ let s = !0;
74
74
  const i = () => {
75
- o && (window.google?.accounts?.id?.initialize({
75
+ s && (window.google?.accounts?.id?.initialize({
76
76
  client_id: e.googleClientId,
77
- callback: p,
77
+ callback: m,
78
78
  auto_select: !1,
79
79
  cancel_on_tap_outside: !0
80
- }), o && f(!0));
80
+ }), s && f(!0));
81
81
  };
82
82
  return O.load().then(() => {
83
- o && i();
83
+ s && i();
84
84
  }).catch(() => {
85
- o && n({
85
+ s && n({
86
86
  code: "SERVER_ERROR",
87
- message: "Failed to load Google Sign-In"
87
+ message: "Unable to load Google sign-in. Please refresh and try again."
88
88
  });
89
89
  }), () => {
90
- o = !1;
90
+ s = !1;
91
91
  };
92
- }, [e.googleClientId, p]);
93
- const S = R(async () => {
92
+ }, [e.googleClientId, m]);
93
+ const y = R(async () => {
94
94
  if (!e.googleClientId) {
95
- const o = {
95
+ const s = {
96
96
  code: "VALIDATION_ERROR",
97
97
  message: "Google Client ID not configured"
98
98
  };
99
- throw n(o), o;
99
+ throw n(s), s;
100
100
  }
101
101
  if (!t) {
102
- const o = {
102
+ const s = {
103
103
  code: "VALIDATION_ERROR",
104
- message: "Google Sign-In not initialized"
104
+ message: "Google sign-in is not ready yet. Please wait a moment and try again."
105
105
  };
106
- throw n(o), o;
106
+ throw n(s), s;
107
107
  }
108
108
  if (a.current) {
109
- const o = {
109
+ const s = {
110
110
  code: "VALIDATION_ERROR",
111
- message: "Google Sign-In already in progress"
111
+ message: "Google sign-in is already in progress."
112
112
  };
113
- throw n(o), o;
113
+ throw n(s), s;
114
114
  }
115
- return s(!0), n(null), new Promise((o, i) => {
116
- a.current = { resolve: o, reject: i }, window.google?.accounts?.id?.prompt((r) => {
115
+ return o(!0), n(null), new Promise((s, i) => {
116
+ a.current = { resolve: s, reject: i }, window.google?.accounts?.id?.prompt((r) => {
117
117
  if (r.isNotDisplayed()) {
118
118
  const l = {
119
119
  code: "SERVER_ERROR",
120
- message: "Google Sign-In popup was blocked. Please allow popups or try again."
120
+ message: "Google sign-in popup was blocked. Please allow popups for this site and try again."
121
121
  };
122
- n(l), s(!1), a.current = null, i(l);
122
+ n(l), o(!1), a.current = null, i(l);
123
123
  } else if (r.isSkippedMoment()) {
124
124
  const l = {
125
125
  code: "SERVER_ERROR",
126
- message: "Google Sign-In was cancelled"
126
+ message: "Google sign-in was cancelled."
127
127
  };
128
- n(l), s(!1), a.current = null, i(l);
128
+ n(l), o(!1), a.current = null, i(l);
129
129
  } else if (r.isDismissedMoment()) {
130
130
  const l = {
131
131
  code: "SERVER_ERROR",
132
- message: "Google Sign-In was cancelled"
132
+ message: "Google sign-in was cancelled."
133
133
  };
134
- n(l), s(!1), a.current = null, i(l);
134
+ n(l), o(!1), a.current = null, i(l);
135
135
  }
136
136
  });
137
137
  });
138
138
  }, [e.googleClientId, t]), A = R(() => n(null), []), L = R(() => h(null), []);
139
139
  return {
140
- signIn: S,
140
+ signIn: y,
141
141
  isLoading: d,
142
142
  isInitialized: t,
143
143
  error: E,
144
144
  clearError: A,
145
- pendingLinkIdToken: I,
145
+ pendingLinkIdToken: b,
146
146
  clearPendingLink: L
147
147
  };
148
148
  }
@@ -150,16 +150,16 @@ function D({
150
150
  onSuccess: e,
151
151
  onError: c,
152
152
  className: d = "",
153
- variant: s = "default",
153
+ variant: o = "default",
154
154
  size: t = "md",
155
155
  disabled: f = !1
156
156
  }) {
157
- const { signIn: E, isLoading: n, isInitialized: I } = M(), h = async () => {
157
+ const { signIn: E, isLoading: n, isInitialized: b } = P(), h = async () => {
158
158
  try {
159
159
  await E(), e?.();
160
160
  } catch (u) {
161
- const p = u instanceof Error ? u : new Error(String(u));
162
- c?.(p);
161
+ const m = u instanceof Error ? u : new Error(String(u));
162
+ c?.(m);
163
163
  }
164
164
  }, a = {
165
165
  sm: "cedros-button-sm",
@@ -173,9 +173,9 @@ function D({
173
173
  className: `cedros-button ${{
174
174
  default: "cedros-button-social",
175
175
  outline: "cedros-button-social-outline"
176
- }[s]} ${a[t]} ${d}`,
176
+ }[o]} ${a[t]} ${d}`,
177
177
  onClick: h,
178
- disabled: f || !I || n,
178
+ disabled: f || !b || n,
179
179
  "aria-label": "Sign in with Google",
180
180
  children: [
181
181
  n ? /* @__PURE__ */ g(z, { size: "sm" }) : /* @__PURE__ */ k(
@@ -226,5 +226,5 @@ function D({
226
226
  }
227
227
  export {
228
228
  D as G,
229
- M as u
229
+ P as u
230
230
  };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GoogleLoginButton-DEbiQngr.js","sources":["../src/hooks/useGoogleAuth.ts","../src/components/google/GoogleLoginButton.tsx"],"sourcesContent":["import { useState, useCallback, useEffect, useRef, useMemo } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\nimport { ApiClient, handleApiError } from '../utils/apiClient';\nimport type { AuthResponse, AuthError } from '../types';\n\n/**\n * Module-level singleton for Google script loading (P-01)\n *\n * Prevents race conditions when multiple components mount simultaneously.\n * Uses a promise queue pattern to ensure the script is only loaded once.\n *\n * ## SSR Limitations (F-08)\n *\n * This singleton persists across the module lifecycle. In SSR environments:\n * - Module state persists between requests (potential cross-request leakage)\n * - Google Sign-In requires browser APIs (document, window)\n * - The hook guards against SSR with `googleClientId` checks\n *\n * For SSR frameworks (Next.js, Remix), ensure this hook is only used\n * in client-side components.\n *\n * ## Test Isolation\n *\n * For test isolation, call `scriptLoader._reset()` in test setup/teardown.\n *\n * @internal\n */\nconst scriptLoader = {\n loading: false,\n loaded: false,\n error: null as Error | null,\n callbacks: [] as Array<{ resolve: () => void; reject: (err: Error) => void }>,\n\n load(): Promise<void> {\n // SSR guard: avoid touching browser globals when running in Node/SSR.\n if (typeof window === 'undefined' || typeof document === 'undefined') {\n return Promise.reject(new Error('Google Sign-In script loader cannot run in SSR'));\n }\n\n // Already loaded\n if (this.loaded) {\n return Promise.resolve();\n }\n\n // Loading in progress - queue callback\n if (this.loading) {\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n });\n }\n\n // Start loading\n this.loading = true;\n return new Promise((resolve, reject) => {\n this.callbacks.push({ resolve, reject });\n\n // Check if script already exists (from previous session or SSR)\n const existingScript = document.getElementById('google-gsi-script');\n if (existingScript) {\n if (window.google?.accounts?.id) {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n } else {\n existingScript.addEventListener('load', () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n });\n }\n return;\n }\n\n const script = document.createElement('script');\n script.src = 'https://accounts.google.com/gsi/client';\n script.async = true;\n script.defer = true;\n script.id = 'google-gsi-script';\n\n script.onload = () => {\n this.loaded = true;\n this.loading = false;\n this.callbacks.forEach((cb) => cb.resolve());\n this.callbacks = [];\n };\n\n script.onerror = () => {\n this.loading = false;\n // M-02: Remove failed script from DOM to allow retry on next load() call.\n // Without removal, retry finds existingScript and waits for a load event\n // that will never fire on an already-failed script.\n script.remove();\n const error = new Error('Failed to load Google Sign-In script');\n this.callbacks.forEach((cb) => cb.reject(error));\n this.callbacks = [];\n };\n\n document.head.appendChild(script);\n });\n },\n\n /**\n * Reset singleton state for test isolation (F-08)\n * @internal - Only use in test setup/teardown\n */\n _reset(): void {\n this.loading = false;\n this.loaded = false;\n this.error = null;\n this.callbacks = [];\n },\n};\n\n/** @internal */\nexport const _internalGoogleScriptLoader = scriptLoader;\n\nexport interface UseGoogleAuthReturn {\n signIn: () => Promise<AuthResponse>;\n isLoading: boolean;\n isInitialized: boolean;\n error: AuthError | null;\n clearError: () => void;\n /** ID token saved when ACCOUNT_LINK_REQUIRED is returned. Pass to POST /auth/link-oauth with the user's password. */\n pendingLinkIdToken: string | null;\n /** Clear the pending link state */\n clearPendingLink: () => void;\n}\n\ninterface PromiseCallbacks {\n resolve: (value: AuthResponse) => void;\n reject: (error: AuthError) => void;\n}\n\n/**\n * Hook for Google OAuth authentication.\n *\n * @example\n * ```tsx\n * function GoogleButton() {\n * const { signIn, isLoading, isInitialized, error } = useGoogleAuth();\n *\n * return (\n * <button onClick={signIn} disabled={!isInitialized || isLoading}>\n * {isLoading ? 'Signing in...' : 'Sign in with Google'}\n * </button>\n * );\n * }\n * ```\n */\nexport function useGoogleAuth(): UseGoogleAuthReturn {\n const { config, _internal } = useCedrosLogin();\n const [isLoading, setIsLoading] = useState(false);\n const [isInitialized, setIsInitialized] = useState(false);\n const [error, setError] = useState<AuthError | null>(null);\n\n const [pendingLinkIdToken, setPendingLinkIdToken] = useState<string | null>(null);\n\n const promiseCallbacksRef = useRef<PromiseCallbacks | null>(null);\n const configRef = useRef(config);\n\n const apiClient = useMemo(\n () =>\n new ApiClient({\n baseUrl: config.serverUrl,\n timeoutMs: config.requestTimeout,\n retryAttempts: config.retryAttempts,\n }),\n [config.serverUrl, config.requestTimeout, config.retryAttempts]\n );\n\n // Keep config ref in sync\n useEffect(() => {\n configRef.current = config;\n }, [config]);\n\n // Handle credential response from Google\n const handleCredentialResponse = useCallback(\n async (response: { credential: string }) => {\n const callbacks = promiseCallbacksRef.current;\n if (!callbacks) return;\n\n try {\n const data = await apiClient.post<AuthResponse>('/google', {\n idToken: response.credential,\n });\n configRef.current.callbacks?.onLoginSuccess?.(data.user, 'google');\n _internal?.handleLoginSuccess(data.user, data.tokens);\n setIsLoading(false);\n callbacks.resolve(data);\n } catch (err) {\n const authError = handleApiError(err, 'Unable to sign in with Google. Please try again.');\n if (authError.code === 'ACCOUNT_LINK_REQUIRED') {\n setPendingLinkIdToken(response.credential);\n }\n setError(authError);\n setIsLoading(false);\n callbacks.reject(authError);\n } finally {\n promiseCallbacksRef.current = null;\n }\n },\n [apiClient, _internal]\n );\n\n // P-01: Initialize Google Sign-In SDK using singleton loader\n useEffect(() => {\n // Early return if Google auth is not enabled\n if (!config.googleClientId) {\n return;\n }\n\n // Track mounted state to prevent state updates after unmount\n let isMounted = true;\n\n const initializeGoogleSignIn = () => {\n if (!isMounted) return;\n\n window.google?.accounts?.id?.initialize({\n client_id: config.googleClientId!,\n callback: handleCredentialResponse,\n auto_select: false,\n cancel_on_tap_outside: true,\n });\n\n if (isMounted) {\n setIsInitialized(true);\n }\n };\n\n // Use singleton loader to handle script loading\n scriptLoader\n .load()\n .then(() => {\n if (isMounted) {\n initializeGoogleSignIn();\n }\n })\n .catch(() => {\n if (isMounted) {\n setError({\n code: 'SERVER_ERROR',\n message: 'Unable to load Google sign-in. Please refresh and try again.',\n });\n }\n });\n\n return () => {\n isMounted = false;\n };\n }, [config.googleClientId, handleCredentialResponse]);\n\n const signIn = useCallback(async (): Promise<AuthResponse> => {\n if (!config.googleClientId) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google Client ID not configured',\n };\n setError(err);\n throw err;\n }\n\n if (!isInitialized) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google sign-in is not ready yet. Please wait a moment and try again.',\n };\n setError(err);\n throw err;\n }\n\n if (promiseCallbacksRef.current) {\n const err: AuthError = {\n code: 'VALIDATION_ERROR',\n message: 'Google sign-in is already in progress.',\n };\n setError(err);\n throw err;\n }\n\n setIsLoading(true);\n setError(null);\n\n return new Promise<AuthResponse>((resolve, reject) => {\n promiseCallbacksRef.current = { resolve, reject };\n\n // Show Google One Tap prompt\n window.google?.accounts?.id?.prompt((notification) => {\n if (notification.isNotDisplayed()) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: 'Google sign-in popup was blocked. Please allow popups for this site and try again.',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n reject(err);\n } else if (notification.isSkippedMoment()) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: 'Google sign-in was cancelled.',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n reject(err);\n } else if (notification.isDismissedMoment()) {\n const err: AuthError = {\n code: 'SERVER_ERROR',\n message: 'Google sign-in was cancelled.',\n };\n setError(err);\n setIsLoading(false);\n promiseCallbacksRef.current = null;\n reject(err);\n }\n });\n });\n }, [config.googleClientId, isInitialized]);\n\n const clearError = useCallback(() => setError(null), []);\n const clearPendingLink = useCallback(() => setPendingLinkIdToken(null), []);\n\n return {\n signIn,\n isLoading,\n isInitialized,\n error,\n clearError,\n pendingLinkIdToken,\n clearPendingLink,\n };\n}\n\n// Type declaration for Google Identity Services\ndeclare global {\n interface Window {\n google?: {\n accounts?: {\n id?: {\n initialize: (config: {\n client_id: string;\n callback: (response: { credential: string }) => void;\n auto_select?: boolean;\n cancel_on_tap_outside?: boolean;\n }) => void;\n prompt: (\n callback: (notification: {\n isNotDisplayed: () => boolean;\n isSkippedMoment: () => boolean;\n isDismissedMoment: () => boolean;\n getMomentType: () => string;\n }) => void\n ) => void;\n renderButton: (element: HTMLElement, config: object) => void;\n disableAutoSelect: () => void;\n };\n };\n };\n }\n}\n","import { useGoogleAuth } from '../../hooks/useGoogleAuth';\nimport { LoadingSpinner } from '../shared/LoadingSpinner';\n\nexport interface GoogleLoginButtonProps {\n onSuccess?: () => void;\n onError?: (error: Error) => void;\n className?: string;\n variant?: 'default' | 'outline';\n size?: 'sm' | 'md' | 'lg';\n disabled?: boolean;\n}\n\n/**\n * Google OAuth login button\n */\nexport function GoogleLoginButton({\n onSuccess,\n onError,\n className = '',\n variant = 'default',\n size = 'md',\n disabled = false,\n}: GoogleLoginButtonProps) {\n const { signIn, isLoading, isInitialized } = useGoogleAuth();\n\n const handleClick = async () => {\n try {\n await signIn();\n onSuccess?.();\n } catch (err) {\n const error = err instanceof Error ? err : new Error(String(err));\n onError?.(error);\n }\n };\n\n const sizeClasses = {\n sm: 'cedros-button-sm',\n md: 'cedros-button-md',\n lg: 'cedros-button-lg',\n };\n\n const variantClasses = {\n default: 'cedros-button-social',\n outline: 'cedros-button-social-outline',\n };\n\n return (\n <button\n type=\"button\"\n className={`cedros-button ${variantClasses[variant]} ${sizeClasses[size]} ${className}`}\n onClick={handleClick}\n disabled={disabled || !isInitialized || isLoading}\n aria-label=\"Sign in with Google\"\n >\n {isLoading ? (\n <LoadingSpinner size=\"sm\" />\n ) : (\n <svg\n className=\"cedros-button-icon\"\n width=\"18\"\n height=\"18\"\n viewBox=\"0 0 18 18\"\n fill=\"none\"\n aria-hidden=\"true\"\n >\n <path\n d=\"M17.64 9.2c0-.637-.057-1.251-.164-1.84H9v3.481h4.844c-.209 1.125-.843 2.078-1.796 2.717v2.258h2.908c1.702-1.567 2.684-3.874 2.684-6.615z\"\n fill=\"#4285F4\"\n />\n <path\n d=\"M9.003 18c2.43 0 4.467-.806 5.956-2.18l-2.909-2.26c-.806.54-1.836.86-3.047.86-2.344 0-4.328-1.584-5.036-3.711H.96v2.332A8.997 8.997 0 0 0 9.003 18z\"\n fill=\"#34A853\"\n />\n <path\n d=\"M3.964 10.712A5.41 5.41 0 0 1 3.682 9c0-.593.102-1.17.282-1.71V4.958H.96A8.996 8.996 0 0 0 0 9c0 1.452.348 2.827.96 4.042l3.004-2.33z\"\n fill=\"#FBBC05\"\n />\n <path\n d=\"M9.003 3.58c1.321 0 2.508.454 3.44 1.345l2.582-2.58C13.464.891 11.428 0 9.002 0A8.997 8.997 0 0 0 .96 4.958l3.005 2.332c.708-2.127 2.692-3.71 5.036-3.71z\"\n fill=\"#EA4335\"\n />\n </svg>\n )}\n <span>Continue with Google</span>\n </button>\n );\n}\n"],"names":["scriptLoader","resolve","reject","existingScript","cb","script","error","useGoogleAuth","config","_internal","useCedrosLogin","isLoading","setIsLoading","useState","isInitialized","setIsInitialized","setError","pendingLinkIdToken","setPendingLinkIdToken","promiseCallbacksRef","useRef","configRef","apiClient","useMemo","ApiClient","useEffect","handleCredentialResponse","useCallback","response","callbacks","data","err","authError","handleApiError","isMounted","initializeGoogleSignIn","signIn","notification","clearError","clearPendingLink","GoogleLoginButton","onSuccess","onError","className","variant","size","disabled","handleClick","sizeClasses","jsxs","jsx","LoadingSpinner"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"LoadingSpinner-6vml-zwr.js","sources":["../src/context/CedrosLoginContext.ts","../src/components/shared/LoadingSpinner.tsx"],"sourcesContent":["import { createContext } from 'react';\nimport type { CedrosLoginConfig, AuthUser, AuthState, AuthError, TokenPair } from '../types';\n\n/**\n * Internal helpers for auth hooks (not part of public API)\n */\nexport interface CedrosLoginInternalAPI {\n handleLoginSuccess: (user: AuthUser, tokens?: TokenPair) => void;\n getAccessToken: () => string | null;\n}\n\n/**\n * Auth state context — changes only on login/logout/token refresh.\n *\n * Subscribing to this context alone avoids re-renders from UI state\n * changes (modal open/close, error display).\n */\nexport interface AuthStateContextValue {\n config: CedrosLoginConfig;\n user: AuthUser | null;\n authState: AuthState;\n logout: () => Promise<void>;\n refreshUser: () => Promise<void>;\n _internal?: CedrosLoginInternalAPI;\n}\n\n/**\n * UI state context — changes on modal/error state changes.\n *\n * Subscribing to this context alone avoids re-renders from auth state\n * changes (login, token refresh).\n */\nexport interface AuthUIContextValue {\n error: AuthError | null;\n isModalOpen: boolean;\n openModal: () => void;\n closeModal: () => void;\n}\n\n/**\n * Combined context value (backward-compatible with existing consumers)\n */\nexport interface CedrosLoginContextValue extends AuthStateContextValue, AuthUIContextValue {}\n\nexport const AuthStateContext = createContext<AuthStateContextValue | null>(null);\nexport const AuthUIContext = createContext<AuthUIContextValue | null>(null);\n\n/**\n * @deprecated Use AuthStateContext + AuthUIContext directly for better performance.\n * Kept for backward compatibility with useCedrosLogin.\n */\nexport const CedrosLoginContext = createContext<CedrosLoginContextValue | null>(null);\n","import { memo, type CSSProperties } from 'react';\n\nexport interface LoadingSpinnerProps {\n size?: 'sm' | 'md' | 'lg' | 'xl';\n className?: string;\n style?: CSSProperties;\n /** Custom label for screen readers (default: \"Loading\") */\n label?: string;\n /** If true, announce the loading state to screen readers */\n announce?: boolean;\n}\n\nconst sizeMap = {\n sm: 16,\n md: 24,\n lg: 32,\n xl: 48, // H-04: Added for WalletUnlock component\n};\n\n/**\n * Accessible loading spinner component.\n * Announces loading state to screen readers when announce prop is true.\n * Wrapped with React.memo to prevent unnecessary re-renders.\n */\nexport const LoadingSpinner = memo(function LoadingSpinner({\n size = 'md',\n className = '',\n style,\n label = 'Loading',\n announce = false,\n}: LoadingSpinnerProps) {\n const dimension = sizeMap[size];\n\n const spinner = (\n <svg\n className={`cedros-spinner ${className}`}\n width={dimension}\n height={dimension}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n style={style}\n aria-label={label}\n role=\"status\"\n aria-hidden={announce ? 'true' : undefined}\n >\n <circle\n className=\"cedros-spinner-track\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeOpacity=\"0.25\"\n />\n <circle\n className=\"cedros-spinner-head\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeDasharray=\"31.4 31.4\"\n transform=\"rotate(-90 12 12)\"\n >\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"1s\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n );\n\n // Wrap in aria-live region if announce is true\n if (announce) {\n return (\n <span aria-live=\"polite\" aria-busy=\"true\">\n {spinner}\n <span className=\"cedros-sr-only\">{label}</span>\n </span>\n );\n }\n\n return spinner;\n});\n"],"names":["AuthStateContext","createContext","AuthUIContext","CedrosLoginContext","sizeMap","LoadingSpinner","memo","size","className","style","label","announce","dimension","spinner","jsxs","jsx"],"mappings":";;AA4CO,MAAMA,IAAmBC,EAA4C,IAAI,GACnEC,IAAgBD,EAAyC,IAAI,GAM7DE,IAAqBF,EAA8C,IAAI,GCvC9EG,IAAU;AAAA,EACd,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA;AACN,GAOaC,IAAiBC,EAAK,SAAwB;AAAA,EACzD,MAAAC,IAAO;AAAA,EACP,WAAAC,IAAY;AAAA,EACZ,OAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,UAAAC,IAAW;AACb,GAAwB;AACtB,QAAMC,IAAYR,EAAQG,CAAI,GAExBM,IACJ,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,kBAAkBN,CAAS;AAAA,MACtC,OAAOI;AAAA,MACP,QAAQA;AAAA,MACR,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAAH;AAAA,MACA,cAAYC;AAAA,MACZ,MAAK;AAAA,MACL,eAAaC,IAAW,SAAS;AAAA,MAEjC,UAAA;AAAA,QAAA,gBAAAI;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,IAAG;AAAA,YACH,IAAG;AAAA,YACH,GAAE;AAAA,YACF,QAAO;AAAA,YACP,aAAY;AAAA,YACZ,eAAc;AAAA,UAAA;AAAA,QAAA;AAAA,QAEhB,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,IAAG;AAAA,YACH,IAAG;AAAA,YACH,GAAE;AAAA,YACF,QAAO;AAAA,YACP,aAAY;AAAA,YACZ,eAAc;AAAA,YACd,iBAAgB;AAAA,YAChB,WAAU;AAAA,YAEV,UAAA,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,eAAc;AAAA,gBACd,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,IAAG;AAAA,gBACH,KAAI;AAAA,gBACJ,aAAY;AAAA,cAAA;AAAA,YAAA;AAAA,UACd;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA;AAKJ,SAAIJ,IAEA,gBAAAG,EAAC,QAAA,EAAK,aAAU,UAAS,aAAU,QAChC,UAAA;AAAA,IAAAD;AAAA,IACD,gBAAAE,EAAC,QAAA,EAAK,WAAU,kBAAkB,UAAAL,EAAA,CAAM;AAAA,EAAA,GAC1C,IAIGG;AACT,CAAC;"}
1
+ {"version":3,"file":"LoadingSpinner-6vml-zwr.js","sources":["../src/context/CedrosLoginContext.ts","../src/components/shared/LoadingSpinner.tsx"],"sourcesContent":["import { createContext } from 'react';\nimport type { CedrosLoginConfig, AuthUser, AuthState, AuthError, TokenPair } from '../types';\n\n/**\n * Internal helpers for auth hooks (not part of public API)\n */\nexport interface CedrosLoginInternalAPI {\n handleLoginSuccess: (user: AuthUser, tokens?: TokenPair) => void;\n getAccessToken: () => string | null;\n}\n\n/**\n * Auth state context — changes only on login/logout/token refresh.\n *\n * Subscribing to this context alone avoids re-renders from UI state\n * changes (modal open/close, error display).\n */\nexport interface AuthStateContextValue {\n config: CedrosLoginConfig;\n user: AuthUser | null;\n authState: AuthState;\n logout: () => Promise<void>;\n refreshUser: () => Promise<void>;\n /** Display order for social login buttons (from server auto-discovery). */\n socialButtonOrder?: string[];\n _internal?: CedrosLoginInternalAPI;\n}\n\n/**\n * UI state context — changes on modal/error state changes.\n *\n * Subscribing to this context alone avoids re-renders from auth state\n * changes (login, token refresh).\n */\nexport interface AuthUIContextValue {\n error: AuthError | null;\n isModalOpen: boolean;\n openModal: () => void;\n closeModal: () => void;\n}\n\n/**\n * Combined context value (backward-compatible with existing consumers)\n */\nexport interface CedrosLoginContextValue extends AuthStateContextValue, AuthUIContextValue {}\n\nexport const AuthStateContext = createContext<AuthStateContextValue | null>(null);\nexport const AuthUIContext = createContext<AuthUIContextValue | null>(null);\n\n/**\n * @deprecated Use AuthStateContext + AuthUIContext directly for better performance.\n * Kept for backward compatibility with useCedrosLogin.\n */\nexport const CedrosLoginContext = createContext<CedrosLoginContextValue | null>(null);\n","import { memo, type CSSProperties } from 'react';\n\nexport interface LoadingSpinnerProps {\n size?: 'sm' | 'md' | 'lg' | 'xl';\n className?: string;\n style?: CSSProperties;\n /** Custom label for screen readers (default: \"Loading\") */\n label?: string;\n /** If true, announce the loading state to screen readers */\n announce?: boolean;\n}\n\nconst sizeMap = {\n sm: 16,\n md: 24,\n lg: 32,\n xl: 48, // H-04: Added for WalletUnlock component\n};\n\n/**\n * Accessible loading spinner component.\n * Announces loading state to screen readers when announce prop is true.\n * Wrapped with React.memo to prevent unnecessary re-renders.\n */\nexport const LoadingSpinner = memo(function LoadingSpinner({\n size = 'md',\n className = '',\n style,\n label = 'Loading',\n announce = false,\n}: LoadingSpinnerProps) {\n const dimension = sizeMap[size];\n\n const spinner = (\n <svg\n className={`cedros-spinner ${className}`}\n width={dimension}\n height={dimension}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n style={style}\n aria-label={label}\n role=\"status\"\n aria-hidden={announce ? 'true' : undefined}\n >\n <circle\n className=\"cedros-spinner-track\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeOpacity=\"0.25\"\n />\n <circle\n className=\"cedros-spinner-head\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeDasharray=\"31.4 31.4\"\n transform=\"rotate(-90 12 12)\"\n >\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"1s\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n );\n\n // Wrap in aria-live region if announce is true\n if (announce) {\n return (\n <span aria-live=\"polite\" aria-busy=\"true\">\n {spinner}\n <span className=\"cedros-sr-only\">{label}</span>\n </span>\n );\n }\n\n return spinner;\n});\n"],"names":["AuthStateContext","createContext","AuthUIContext","CedrosLoginContext","sizeMap","LoadingSpinner","memo","size","className","style","label","announce","dimension","spinner","jsxs","jsx"],"mappings":";;AA8CO,MAAMA,IAAmBC,EAA4C,IAAI,GACnEC,IAAgBD,EAAyC,IAAI,GAM7DE,IAAqBF,EAA8C,IAAI,GCzC9EG,IAAU;AAAA,EACd,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA;AACN,GAOaC,IAAiBC,EAAK,SAAwB;AAAA,EACzD,MAAAC,IAAO;AAAA,EACP,WAAAC,IAAY;AAAA,EACZ,OAAAC;AAAA,EACA,OAAAC,IAAQ;AAAA,EACR,UAAAC,IAAW;AACb,GAAwB;AACtB,QAAMC,IAAYR,EAAQG,CAAI,GAExBM,IACJ,gBAAAC;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,WAAW,kBAAkBN,CAAS;AAAA,MACtC,OAAOI;AAAA,MACP,QAAQA;AAAA,MACR,SAAQ;AAAA,MACR,MAAK;AAAA,MACL,OAAAH;AAAA,MACA,cAAYC;AAAA,MACZ,MAAK;AAAA,MACL,eAAaC,IAAW,SAAS;AAAA,MAEjC,UAAA;AAAA,QAAA,gBAAAI;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,IAAG;AAAA,YACH,IAAG;AAAA,YACH,GAAE;AAAA,YACF,QAAO;AAAA,YACP,aAAY;AAAA,YACZ,eAAc;AAAA,UAAA;AAAA,QAAA;AAAA,QAEhB,gBAAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,WAAU;AAAA,YACV,IAAG;AAAA,YACH,IAAG;AAAA,YACH,GAAE;AAAA,YACF,QAAO;AAAA,YACP,aAAY;AAAA,YACZ,eAAc;AAAA,YACd,iBAAgB;AAAA,YAChB,WAAU;AAAA,YAEV,UAAA,gBAAAA;AAAA,cAAC;AAAA,cAAA;AAAA,gBACC,eAAc;AAAA,gBACd,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,IAAG;AAAA,gBACH,KAAI;AAAA,gBACJ,aAAY;AAAA,cAAA;AAAA,YAAA;AAAA,UACd;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EAAA;AAKJ,SAAIJ,IAEA,gBAAAG,EAAC,QAAA,EAAK,aAAU,UAAS,aAAU,QAChC,UAAA;AAAA,IAAAD;AAAA,IACD,gBAAAE,EAAC,QAAA,EAAK,WAAU,kBAAkB,UAAAL,EAAA,CAAM;AAAA,EAAA,GAC1C,IAIGG;AACT,CAAC;"}
@@ -1 +1 @@
1
- {"version":3,"file":"LoadingSpinner-d6sSxgQN.cjs","sources":["../src/context/CedrosLoginContext.ts","../src/components/shared/LoadingSpinner.tsx"],"sourcesContent":["import { createContext } from 'react';\nimport type { CedrosLoginConfig, AuthUser, AuthState, AuthError, TokenPair } from '../types';\n\n/**\n * Internal helpers for auth hooks (not part of public API)\n */\nexport interface CedrosLoginInternalAPI {\n handleLoginSuccess: (user: AuthUser, tokens?: TokenPair) => void;\n getAccessToken: () => string | null;\n}\n\n/**\n * Auth state context — changes only on login/logout/token refresh.\n *\n * Subscribing to this context alone avoids re-renders from UI state\n * changes (modal open/close, error display).\n */\nexport interface AuthStateContextValue {\n config: CedrosLoginConfig;\n user: AuthUser | null;\n authState: AuthState;\n logout: () => Promise<void>;\n refreshUser: () => Promise<void>;\n _internal?: CedrosLoginInternalAPI;\n}\n\n/**\n * UI state context — changes on modal/error state changes.\n *\n * Subscribing to this context alone avoids re-renders from auth state\n * changes (login, token refresh).\n */\nexport interface AuthUIContextValue {\n error: AuthError | null;\n isModalOpen: boolean;\n openModal: () => void;\n closeModal: () => void;\n}\n\n/**\n * Combined context value (backward-compatible with existing consumers)\n */\nexport interface CedrosLoginContextValue extends AuthStateContextValue, AuthUIContextValue {}\n\nexport const AuthStateContext = createContext<AuthStateContextValue | null>(null);\nexport const AuthUIContext = createContext<AuthUIContextValue | null>(null);\n\n/**\n * @deprecated Use AuthStateContext + AuthUIContext directly for better performance.\n * Kept for backward compatibility with useCedrosLogin.\n */\nexport const CedrosLoginContext = createContext<CedrosLoginContextValue | null>(null);\n","import { memo, type CSSProperties } from 'react';\n\nexport interface LoadingSpinnerProps {\n size?: 'sm' | 'md' | 'lg' | 'xl';\n className?: string;\n style?: CSSProperties;\n /** Custom label for screen readers (default: \"Loading\") */\n label?: string;\n /** If true, announce the loading state to screen readers */\n announce?: boolean;\n}\n\nconst sizeMap = {\n sm: 16,\n md: 24,\n lg: 32,\n xl: 48, // H-04: Added for WalletUnlock component\n};\n\n/**\n * Accessible loading spinner component.\n * Announces loading state to screen readers when announce prop is true.\n * Wrapped with React.memo to prevent unnecessary re-renders.\n */\nexport const LoadingSpinner = memo(function LoadingSpinner({\n size = 'md',\n className = '',\n style,\n label = 'Loading',\n announce = false,\n}: LoadingSpinnerProps) {\n const dimension = sizeMap[size];\n\n const spinner = (\n <svg\n className={`cedros-spinner ${className}`}\n width={dimension}\n height={dimension}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n style={style}\n aria-label={label}\n role=\"status\"\n aria-hidden={announce ? 'true' : undefined}\n >\n <circle\n className=\"cedros-spinner-track\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeOpacity=\"0.25\"\n />\n <circle\n className=\"cedros-spinner-head\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeDasharray=\"31.4 31.4\"\n transform=\"rotate(-90 12 12)\"\n >\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"1s\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n );\n\n // Wrap in aria-live region if announce is true\n if (announce) {\n return (\n <span aria-live=\"polite\" aria-busy=\"true\">\n {spinner}\n <span className=\"cedros-sr-only\">{label}</span>\n </span>\n );\n }\n\n return spinner;\n});\n"],"names":["AuthStateContext","createContext","AuthUIContext","CedrosLoginContext","sizeMap","LoadingSpinner","memo","size","className","style","label","announce","dimension","spinner","jsxs","jsx"],"mappings":"qEA4CaA,EAAmBC,EAAAA,cAA4C,IAAI,EACnEC,EAAgBD,EAAAA,cAAyC,IAAI,EAM7DE,EAAqBF,EAAAA,cAA8C,IAAI,ECvC9EG,EAAU,CACd,GAAI,GACJ,GAAI,GACJ,GAAI,GACJ,GAAI,EACN,EAOaC,EAAiBC,EAAAA,KAAK,SAAwB,CACzD,KAAAC,EAAO,KACP,UAAAC,EAAY,GACZ,MAAAC,EACA,MAAAC,EAAQ,UACR,SAAAC,EAAW,EACb,EAAwB,CACtB,MAAMC,EAAYR,EAAQG,CAAI,EAExBM,EACJC,EAAAA,KAAC,MAAA,CACC,UAAW,kBAAkBN,CAAS,GACtC,MAAOI,EACP,OAAQA,EACR,QAAQ,YACR,KAAK,OACL,MAAAH,EACA,aAAYC,EACZ,KAAK,SACL,cAAaC,EAAW,OAAS,OAEjC,SAAA,CAAAI,EAAAA,IAAC,SAAA,CACC,UAAU,uBACV,GAAG,KACH,GAAG,KACH,EAAE,KACF,OAAO,eACP,YAAY,IACZ,cAAc,MAAA,CAAA,EAEhBA,EAAAA,IAAC,SAAA,CACC,UAAU,sBACV,GAAG,KACH,GAAG,KACH,EAAE,KACF,OAAO,eACP,YAAY,IACZ,cAAc,QACd,gBAAgB,YAChB,UAAU,oBAEV,SAAAA,EAAAA,IAAC,mBAAA,CACC,cAAc,YACd,KAAK,SACL,KAAK,UACL,GAAG,YACH,IAAI,KACJ,YAAY,YAAA,CAAA,CACd,CAAA,CACF,CAAA,CAAA,EAKJ,OAAIJ,EAEAG,EAAAA,KAAC,OAAA,CAAK,YAAU,SAAS,YAAU,OAChC,SAAA,CAAAD,EACDE,EAAAA,IAAC,OAAA,CAAK,UAAU,iBAAkB,SAAAL,CAAA,CAAM,CAAA,EAC1C,EAIGG,CACT,CAAC"}
1
+ {"version":3,"file":"LoadingSpinner-d6sSxgQN.cjs","sources":["../src/context/CedrosLoginContext.ts","../src/components/shared/LoadingSpinner.tsx"],"sourcesContent":["import { createContext } from 'react';\nimport type { CedrosLoginConfig, AuthUser, AuthState, AuthError, TokenPair } from '../types';\n\n/**\n * Internal helpers for auth hooks (not part of public API)\n */\nexport interface CedrosLoginInternalAPI {\n handleLoginSuccess: (user: AuthUser, tokens?: TokenPair) => void;\n getAccessToken: () => string | null;\n}\n\n/**\n * Auth state context — changes only on login/logout/token refresh.\n *\n * Subscribing to this context alone avoids re-renders from UI state\n * changes (modal open/close, error display).\n */\nexport interface AuthStateContextValue {\n config: CedrosLoginConfig;\n user: AuthUser | null;\n authState: AuthState;\n logout: () => Promise<void>;\n refreshUser: () => Promise<void>;\n /** Display order for social login buttons (from server auto-discovery). */\n socialButtonOrder?: string[];\n _internal?: CedrosLoginInternalAPI;\n}\n\n/**\n * UI state context — changes on modal/error state changes.\n *\n * Subscribing to this context alone avoids re-renders from auth state\n * changes (login, token refresh).\n */\nexport interface AuthUIContextValue {\n error: AuthError | null;\n isModalOpen: boolean;\n openModal: () => void;\n closeModal: () => void;\n}\n\n/**\n * Combined context value (backward-compatible with existing consumers)\n */\nexport interface CedrosLoginContextValue extends AuthStateContextValue, AuthUIContextValue {}\n\nexport const AuthStateContext = createContext<AuthStateContextValue | null>(null);\nexport const AuthUIContext = createContext<AuthUIContextValue | null>(null);\n\n/**\n * @deprecated Use AuthStateContext + AuthUIContext directly for better performance.\n * Kept for backward compatibility with useCedrosLogin.\n */\nexport const CedrosLoginContext = createContext<CedrosLoginContextValue | null>(null);\n","import { memo, type CSSProperties } from 'react';\n\nexport interface LoadingSpinnerProps {\n size?: 'sm' | 'md' | 'lg' | 'xl';\n className?: string;\n style?: CSSProperties;\n /** Custom label for screen readers (default: \"Loading\") */\n label?: string;\n /** If true, announce the loading state to screen readers */\n announce?: boolean;\n}\n\nconst sizeMap = {\n sm: 16,\n md: 24,\n lg: 32,\n xl: 48, // H-04: Added for WalletUnlock component\n};\n\n/**\n * Accessible loading spinner component.\n * Announces loading state to screen readers when announce prop is true.\n * Wrapped with React.memo to prevent unnecessary re-renders.\n */\nexport const LoadingSpinner = memo(function LoadingSpinner({\n size = 'md',\n className = '',\n style,\n label = 'Loading',\n announce = false,\n}: LoadingSpinnerProps) {\n const dimension = sizeMap[size];\n\n const spinner = (\n <svg\n className={`cedros-spinner ${className}`}\n width={dimension}\n height={dimension}\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n style={style}\n aria-label={label}\n role=\"status\"\n aria-hidden={announce ? 'true' : undefined}\n >\n <circle\n className=\"cedros-spinner-track\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeOpacity=\"0.25\"\n />\n <circle\n className=\"cedros-spinner-head\"\n cx=\"12\"\n cy=\"12\"\n r=\"10\"\n stroke=\"currentColor\"\n strokeWidth=\"3\"\n strokeLinecap=\"round\"\n strokeDasharray=\"31.4 31.4\"\n transform=\"rotate(-90 12 12)\"\n >\n <animateTransform\n attributeName=\"transform\"\n type=\"rotate\"\n from=\"0 12 12\"\n to=\"360 12 12\"\n dur=\"1s\"\n repeatCount=\"indefinite\"\n />\n </circle>\n </svg>\n );\n\n // Wrap in aria-live region if announce is true\n if (announce) {\n return (\n <span aria-live=\"polite\" aria-busy=\"true\">\n {spinner}\n <span className=\"cedros-sr-only\">{label}</span>\n </span>\n );\n }\n\n return spinner;\n});\n"],"names":["AuthStateContext","createContext","AuthUIContext","CedrosLoginContext","sizeMap","LoadingSpinner","memo","size","className","style","label","announce","dimension","spinner","jsxs","jsx"],"mappings":"qEA8CaA,EAAmBC,EAAAA,cAA4C,IAAI,EACnEC,EAAgBD,EAAAA,cAAyC,IAAI,EAM7DE,EAAqBF,EAAAA,cAA8C,IAAI,ECzC9EG,EAAU,CACd,GAAI,GACJ,GAAI,GACJ,GAAI,GACJ,GAAI,EACN,EAOaC,EAAiBC,EAAAA,KAAK,SAAwB,CACzD,KAAAC,EAAO,KACP,UAAAC,EAAY,GACZ,MAAAC,EACA,MAAAC,EAAQ,UACR,SAAAC,EAAW,EACb,EAAwB,CACtB,MAAMC,EAAYR,EAAQG,CAAI,EAExBM,EACJC,EAAAA,KAAC,MAAA,CACC,UAAW,kBAAkBN,CAAS,GACtC,MAAOI,EACP,OAAQA,EACR,QAAQ,YACR,KAAK,OACL,MAAAH,EACA,aAAYC,EACZ,KAAK,SACL,cAAaC,EAAW,OAAS,OAEjC,SAAA,CAAAI,EAAAA,IAAC,SAAA,CACC,UAAU,uBACV,GAAG,KACH,GAAG,KACH,EAAE,KACF,OAAO,eACP,YAAY,IACZ,cAAc,MAAA,CAAA,EAEhBA,EAAAA,IAAC,SAAA,CACC,UAAU,sBACV,GAAG,KACH,GAAG,KACH,EAAE,KACF,OAAO,eACP,YAAY,IACZ,cAAc,QACd,gBAAgB,YAChB,UAAU,oBAEV,SAAAA,EAAAA,IAAC,mBAAA,CACC,cAAc,YACd,KAAK,SACL,KAAK,UACL,GAAG,YACH,IAAI,KACJ,YAAY,YAAA,CAAA,CACd,CAAA,CACF,CAAA,CAAA,EAKJ,OAAIJ,EAEAG,EAAAA,KAAC,OAAA,CAAK,YAAU,SAAS,YAAU,OAChC,SAAA,CAAAD,EACDE,EAAAA,IAAC,OAAA,CAAK,UAAU,iBAAkB,SAAAL,CAAA,CAAM,CAAA,EAC1C,EAIGG,CACT,CAAC"}
@@ -1 +1 @@
1
- "use strict";const e=require("react/jsx-runtime"),r=require("react"),k=require("./LoadingSpinner-d6sSxgQN.cjs"),$=require("./ErrorMessage-CHbYbVi2.cjs"),D=require("./sanitization-Bo_tn-L2.cjs"),F=require("./validation-BuGQrA-K.cjs"),A=require("./useCedrosLogin-C9MrcZvh.cjs"),P=require("./useOrgs-DDVRCaVi.cjs"),q=require("./useSystemSettings-DRrreszl.cjs"),U=["owner","admin","member"];function z({members:s,currentUserId:t,isLoading:a=!1,error:i,canManage:n=!1,canChangeRoles:o=!1,onUpdateRole:f,onRemove:m,className:h=""}){const[l,j]=r.useState("name"),[d,y]=r.useState("asc"),p=u=>{l===u?y(d==="asc"?"desc":"asc"):(j(u),y("asc"))},c=r.useMemo(()=>{const u={owner:0,admin:1,member:2};return[...s].sort((g,b)=>{let S,w;switch(l){case"name":S=(g.user.name||g.user.email||"").toLowerCase(),w=(b.user.name||b.user.email||"").toLowerCase();break;case"role":S=u[g.role]??99,w=u[b.role]??99;break;case"joinedAt":S=new Date(g.joinedAt).getTime(),w=new Date(b.joinedAt).getTime();break;default:return 0}return S<w?d==="asc"?-1:1:S>w?d==="asc"?1:-1:0})},[s,l,d]);return a&&s.length===0?e.jsxs("div",{className:`cedros-member-list cedros-member-list-loading ${h}`,children:[e.jsx(k.LoadingSpinner,{}),e.jsx("span",{children:"Loading members..."})]}):i?e.jsx("div",{className:`cedros-member-list ${h}`,children:e.jsx($.ErrorMessage,{error:i})}):s.length===0?e.jsx("div",{className:`cedros-member-list cedros-member-list-empty ${h}`,children:e.jsx("p",{children:"No members found."})}):e.jsx("div",{className:`cedros-member-list ${h}`,children:e.jsxs("table",{className:"cedros-member-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:e.jsxs("button",{type:"button",className:`cedros-admin-sort-button ${l==="name"?"cedros-admin-sort-active":""}`,onClick:()=>p("name"),children:["Member"," ",e.jsx("span",{className:"cedros-admin-sort-icon",children:l==="name"?d==="asc"?"↑":"↓":"↕"})]})}),e.jsx("th",{children:e.jsxs("button",{type:"button",className:`cedros-admin-sort-button ${l==="role"?"cedros-admin-sort-active":""}`,onClick:()=>p("role"),children:["Role"," ",e.jsx("span",{className:"cedros-admin-sort-icon",children:l==="role"?d==="asc"?"↑":"↓":"↕"})]})}),e.jsx("th",{children:e.jsxs("button",{type:"button",className:`cedros-admin-sort-button ${l==="joinedAt"?"cedros-admin-sort-active":""}`,onClick:()=>p("joinedAt"),children:["Joined"," ",e.jsx("span",{className:"cedros-admin-sort-icon",children:l==="joinedAt"?d==="asc"?"↑":"↓":"↕"})]})}),(n||o)&&e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:c.map(u=>e.jsx(B,{member:u,isCurrentUser:u.userId===t,canManage:n,canChangeRoles:o,onUpdateRole:f,onRemove:m},u.id))})]})})}function B({member:s,isCurrentUser:t,canManage:a,canChangeRoles:i,onUpdateRole:n,onRemove:o}){const[f,m]=r.useState(!1),[h,l]=r.useState(s.role),j=r.useCallback(async c=>{if(!(!n||c===s.role)){m(!0);try{await n(s.userId,c),l(c)}catch{l(s.role)}finally{m(!1)}}},[s.userId,s.role,n]),d=r.useCallback(async()=>{if(!(!o||!window.confirm(`Are you sure you want to remove ${s.user.name||s.user.email} from this organization?`))){m(!0);try{await o(s.userId)}finally{m(!1)}}},[s.userId,s.user.name,s.user.email,o]),y=s.role==="owner",p=!t&&!y;return e.jsxs("tr",{className:`cedros-member-row ${t?"cedros-member-row-current":""}`,children:[e.jsxs("td",{className:"cedros-member-info",children:[e.jsx(W,{user:s.user}),e.jsxs("div",{className:"cedros-member-details",children:[e.jsxs("span",{className:"cedros-member-name",children:[s.user.name||"Unknown",t&&e.jsx("span",{className:"cedros-member-you",children:"(you)"})]}),e.jsx("span",{className:"cedros-member-email",children:s.user.email})]})]}),e.jsx("td",{className:"cedros-member-role",children:i&&p&&n?e.jsx("select",{value:h,onChange:c=>j(c.target.value),disabled:f,className:"cedros-role-select",children:U.map(c=>e.jsx("option",{value:c,children:c.charAt(0).toUpperCase()+c.slice(1)},c))}):e.jsx("span",{className:`cedros-role-badge cedros-role-badge-${s.role}`,children:s.role.charAt(0).toUpperCase()+s.role.slice(1)})}),e.jsx("td",{className:"cedros-member-joined",children:H(s.joinedAt)}),(a||i)&&e.jsx("td",{className:"cedros-member-actions",children:a&&p&&o&&e.jsx("button",{type:"button",className:"cedros-button cedros-button-danger cedros-button-sm",onClick:d,disabled:f,"aria-label":`Remove ${s.user.name||s.user.email}`,children:f?e.jsx(k.LoadingSpinner,{size:"sm"}):"Remove"})})]})}function W({user:s}){const t=D.sanitizeImageUrl(s.picture);if(t)return e.jsx("img",{src:t,alt:s.name||s.email||"Member",className:"cedros-member-avatar",referrerPolicy:"no-referrer"});const a=(s.name?.[0]||s.email?.[0]||"?").toUpperCase();return e.jsx("div",{className:"cedros-member-avatar-placeholder",children:a})}function H(s){return new Date(s).toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})}const V=["admin","member"];function K({onSubmit:s,isLoading:t=!1,error:a,availableRoles:i=V,defaultRole:n="member",className:o=""}){const[f,m]=r.useState(""),[h,l]=r.useState(n),[j,d]=r.useState(null),[y,p]=r.useState(!1),c=r.useRef(null),u=r.useRef(!0);r.useEffect(()=>(u.current=!0,()=>{u.current=!1,c.current!==null&&(window.clearTimeout(c.current),c.current=null)}),[]);const g=r.useCallback(async b=>{b.preventDefault(),d(null),p(!1);const S=f.trim();if(!S){d("Email is required");return}if(!F.validateEmail(S)){d("Please enter a valid email address");return}try{await s(S,h),m(""),l(n),p(!0),c.current!==null&&window.clearTimeout(c.current),c.current=window.setTimeout(()=>{u.current&&p(!1),c.current=null},3e3)}catch{}},[f,h,n,s]);return e.jsxs("form",{className:`cedros-invite-form ${o}`,onSubmit:g,children:[(a||j)&&e.jsx($.ErrorMessage,{error:j??a??null}),y&&e.jsxs("div",{className:"cedros-invite-success",role:"status",children:[e.jsx(G,{}),e.jsx("span",{children:"Invitation sent successfully!"})]}),e.jsxs("div",{className:"cedros-invite-form-row",children:[e.jsxs("div",{className:"cedros-form-group cedros-invite-email-group",children:[e.jsx("label",{htmlFor:"invite-email",className:"cedros-form-label",children:"Email Address"}),e.jsx("input",{id:"invite-email",type:"email",className:"cedros-form-input",value:f,onChange:b=>m(b.target.value),placeholder:"colleague@example.com",disabled:t,autoComplete:"email"})]}),e.jsxs("div",{className:"cedros-form-group cedros-invite-role-group",children:[e.jsx("label",{htmlFor:"invite-role",className:"cedros-form-label",children:"Role"}),e.jsx("select",{id:"invite-role",className:"cedros-form-select",value:h,onChange:b=>l(b.target.value),disabled:t,children:i.map(b=>e.jsx("option",{value:b,children:b.charAt(0).toUpperCase()+b.slice(1)},b))})]}),e.jsx("button",{type:"submit",className:"cedros-button cedros-button-primary cedros-invite-submit",disabled:t||!f.trim(),children:t?e.jsx(k.LoadingSpinner,{size:"sm"}):"Send Invite"})]}),e.jsx("p",{className:"cedros-form-hint",children:"The invited user will receive an email with a link to join your organization."})]})}function G(){return e.jsx("svg",{className:"cedros-invite-check",width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M3 8L6 11L13 5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function J({invites:s,isLoading:t=!1,error:a,canManage:i=!1,onCancel:n,onResend:o,className:f=""}){return t&&s.length===0?e.jsxs("div",{className:`cedros-invite-list cedros-invite-list-loading ${f}`,children:[e.jsx(k.LoadingSpinner,{}),e.jsx("span",{children:"Loading invites..."})]}):a?e.jsx("div",{className:`cedros-invite-list ${f}`,children:e.jsx($.ErrorMessage,{error:a})}):s.length===0?e.jsx("div",{className:`cedros-invite-list cedros-invite-list-empty ${f}`,children:e.jsx("p",{children:"No pending invites."})}):e.jsx("div",{className:`cedros-invite-list ${f}`,children:e.jsx("ul",{className:"cedros-invite-items",children:s.map(m=>e.jsx(Y,{invite:m,canManage:i,onCancel:n,onResend:o},m.id))})})}function Y({invite:s,canManage:t,onCancel:a,onResend:i}){const[n,o]=r.useState(!1),[f,m]=r.useState(!1),h=r.useRef(null),l=new Date(s.expiresAt)<new Date,j=r.useCallback(async()=>{if(!(!a||!window.confirm(`Are you sure you want to cancel the invite for ${s.email}?`))){o(!0);try{await a(s.id)}finally{o(!1)}}},[s.id,s.email,a]),d=r.useCallback(async()=>{if(i){o(!0),m(!1);try{await i(s.id),m(!0),h.current!==null&&window.clearTimeout(h.current),h.current=window.setTimeout(()=>{m(!1),h.current=null},3e3)}finally{o(!1)}}},[s.id,i]);return r.useEffect(()=>()=>{h.current!==null&&(window.clearTimeout(h.current),h.current=null)},[]),e.jsxs("li",{className:`cedros-invite-item ${l?"cedros-invite-item-expired":""}`,children:[e.jsxs("div",{className:"cedros-invite-item-info",children:[e.jsxs("div",{className:"cedros-invite-item-main",children:[e.jsx("span",{className:"cedros-invite-item-email",children:s.email}),e.jsx("span",{className:`cedros-role-badge cedros-role-badge-${s.role}`,children:s.role.charAt(0).toUpperCase()+s.role.slice(1)}),l&&e.jsx("span",{className:"cedros-invite-expired-badge",children:"Expired"})]}),e.jsxs("div",{className:"cedros-invite-item-meta",children:[e.jsxs("span",{className:"cedros-invite-item-date",children:["Invited ",M(s.createdAt)]}),!l&&e.jsxs("span",{className:"cedros-invite-item-expires",children:["Expires ",Q(s.expiresAt)]})]})]}),t&&e.jsxs("div",{className:"cedros-invite-item-actions",children:[f&&e.jsx("span",{className:"cedros-invite-resend-success",children:"Sent!"}),i&&!l&&e.jsx("button",{type:"button",className:"cedros-button cedros-button-outline cedros-button-sm",onClick:d,disabled:n,"aria-label":`Resend invite to ${s.email}`,children:n?e.jsx(k.LoadingSpinner,{size:"sm"}):"Resend"}),a&&e.jsx("button",{type:"button",className:"cedros-button cedros-button-danger cedros-button-sm",onClick:j,disabled:n,"aria-label":`Cancel invite for ${s.email}`,children:"Cancel"})]})]})}function M(s){return new Date(s).toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})}function Q(s){const t=new Date(s),a=new Date,i=t.getTime()-a.getTime(),n=Math.ceil(i/(1e3*60*60*24));return n<0?"expired":n===0?"today":n===1?"tomorrow":n<7?`in ${n} days`:M(s)}class X{client;constructor(t,a,i,n){this.client=new A.ApiClient({baseUrl:t,timeoutMs:a,retryAttempts:i,getAccessToken:n})}async listMembers(t,a=50,i=0){try{const n=await this.client.get(`/orgs/${t}/members?limit=${a}&offset=${i}`);return{members:n.members.map(o=>({id:o.id,userId:o.userId,orgId:t,role:o.role,joinedAt:o.joinedAt,user:{id:o.userId,email:o.email,name:o.name}})),total:n.total}}catch(n){throw A.handleApiError(n,"Failed to list members")}}async updateMemberRole(t,a,i){try{return await this.client.patch(`/orgs/${t}/members/${a}`,i)}catch(n){throw A.handleApiError(n,"Failed to update member role")}}async removeMember(t,a){try{await this.client.delete(`/orgs/${t}/members/${a}`)}catch(i){throw A.handleApiError(i,"Failed to remove member")}}}function Z(s){const{config:t,authState:a,_internal:i}=A.useCedrosLogin(),[n,o]=r.useState([]),[f,m]=r.useState(0),[h,l]=r.useState(!1),[j,d]=r.useState(null),y=r.useRef(void 0),p=r.useRef(0),c=r.useMemo(()=>new X(t.serverUrl,t.requestTimeout,t.retryAttempts,i?.getAccessToken),[t.serverUrl,t.requestTimeout,t.retryAttempts,i]),u=r.useRef(c);u.current=c;const g=r.useCallback(async w=>{if(!s||a!=="authenticated"){o([]),m(0);return}l(!0),d(null);const x=++p.current;try{const{limit:v=50,offset:N=0}=w??{},C=await u.current.listMembers(s,v,N);if(x!==p.current)return;o(C.members),m(C.total)}catch(v){if(x!==p.current)return;d(v)}finally{x===p.current&&l(!1)}},[s,a]);r.useEffect(()=>{if(a!=="authenticated"){y.current=void 0;return}s!==y.current&&(y.current=s,g())},[s,a,g]);const b=r.useCallback(async(w,x)=>{if(!s)throw new Error("No organization selected");l(!0),d(null);try{await u.current.updateMemberRole(s,w,{role:x}),await g()}catch(v){throw d(v),v}finally{l(!1)}},[s,g]),S=r.useCallback(async w=>{if(!s)throw new Error("No organization selected");l(!0),d(null);try{await u.current.removeMember(s,w),await g()}catch(x){throw d(x),x}finally{l(!1)}},[s,g]);return{members:n,total:f,isLoading:h,error:j,fetchMembers:g,updateMemberRole:b,removeMember:S}}class ee{client;constructor(t,a,i,n){this.client=new A.ApiClient({baseUrl:t,timeoutMs:a,retryAttempts:i,getAccessToken:n})}async listInvites(t,a=50,i=0){try{const n=await this.client.get(`/orgs/${t}/invites?limit=${a}&offset=${i}`);return{invites:n.invites.map(o=>({id:o.id,orgId:o.orgId,email:o.email,role:o.role,invitedBy:o.invitedBy,createdAt:o.createdAt,expiresAt:o.expiresAt})),total:n.total}}catch(n){throw A.handleApiError(n,"Failed to list invites")}}async createInvite(t,a){try{return await this.client.post(`/orgs/${t}/invites`,a)}catch(i){throw A.handleApiError(i,"Failed to create invite")}}async cancelInvite(t,a){try{await this.client.delete(`/orgs/${t}/invites/${a}`)}catch(i){throw A.handleApiError(i,"Failed to cancel invite")}}async resendInvite(t,a){try{await this.client.post(`/orgs/${t}/invites/${a}/resend`,{})}catch(i){throw A.handleApiError(i,"Failed to resend invite")}}async acceptInvite(t){try{return await this.client.post("/invites/accept",t)}catch(a){throw A.handleApiError(a,"Failed to accept invite")}}}function se(s){const{config:t,authState:a,_internal:i}=A.useCedrosLogin(),[n,o]=r.useState([]),[f,m]=r.useState(0),[h,l]=r.useState(!1),[j,d]=r.useState(null),y=r.useRef(void 0),p=r.useRef(0),c=r.useMemo(()=>new ee(t.serverUrl,t.requestTimeout,t.retryAttempts,i?.getAccessToken),[t.serverUrl,t.requestTimeout,t.retryAttempts,i]),u=r.useRef(c);u.current=c;const g=r.useCallback(async v=>{if(!s||a!=="authenticated"){o([]),m(0);return}l(!0),d(null);const N=++p.current;try{const{limit:C=50,offset:O=0}=v??{},L=await u.current.listInvites(s,C,O);if(N!==p.current)return;o(L.invites),m(L.total)}catch(C){if(N!==p.current)return;d(C)}finally{N===p.current&&l(!1)}},[s,a]);r.useEffect(()=>{if(a!=="authenticated"){y.current=void 0;return}s!==y.current&&(y.current=s,g())},[s,a,g]);const b=r.useCallback(async(v,N="member")=>{if(!s)throw new Error("No organization selected");l(!0),d(null);try{await u.current.createInvite(s,{email:v,role:N}),await g()}catch(C){throw d(C),C}finally{l(!1)}},[s,g]),S=r.useCallback(async v=>{if(!s)throw new Error("No organization selected");l(!0),d(null);try{await u.current.cancelInvite(s,v),await g()}catch(N){throw d(N),N}finally{l(!1)}},[s,g]),w=r.useCallback(async v=>{if(!s)throw new Error("No organization selected");l(!0),d(null);try{await u.current.resendInvite(s,v)}catch(N){throw d(N),N}finally{l(!1)}},[s]),x=r.useCallback(async v=>{l(!0),d(null);try{return await u.current.acceptInvite({token:v})}catch(N){throw d(N),N}finally{l(!1)}},[]);return{invites:n,total:f,isLoading:h,error:j,fetchInvites:g,createInvite:b,cancelInvite:S,resendInvite:w,acceptInvite:x}}const te={organizations:!1,sso:!1,mfa:!1,walletSigning:!1,credits:!1,userWithdrawals:!1,cedrosPay:!1};function I(){const{settings:s,isLoading:t,error:a,fetchSettings:i,getValue:n}=q.useSystemSettings(),[o,f]=r.useState(!1);r.useEffect(()=>{o||(i(),f(!0))},[i,o]);const m=r.useCallback(d=>d===void 0?!1:d==="true"||d==="1",[]),h=r.useMemo(()=>Object.keys(s).length===0?te:{organizations:m(n("feature_organizations")),sso:m(n("feature_sso")),mfa:m(n("feature_mfa")),walletSigning:m(n("feature_wallet_signing")),credits:m(n("feature_credits")),userWithdrawals:m(n("feature_user_withdrawals")),cedrosPay:m(n("feature_cedros_pay"))},[s,n,m]),l=r.useCallback(async()=>{await i()},[i]),j=r.useCallback(d=>h[d],[h]);return{features:h,isLoading:t,error:a,refetch:l,isEnabled:j}}const re=["users","team","deposits","withdrawals","settings-wallet","settings-auth","settings-messaging","settings-credits","settings-server"],ne=["pay-products","pay-subscriptions","pay-transactions","pay-coupons","pay-refunds","pay-storefront","pay-ai","pay-payment","pay-messaging","pay-settings"],E={users:"Users",team:"Team",deposits:"Deposits",withdrawals:"Withdrawals","settings-wallet":"Wallet Settings","settings-auth":"Auth Settings","settings-messaging":"Messages Settings","settings-credits":"Credits Settings","settings-server":"Server Settings","pay-products":"Products","pay-subscriptions":"Subscriptions","pay-transactions":"Transactions","pay-coupons":"Coupons","pay-refunds":"Refunds","pay-storefront":"Storefront","pay-ai":"Store AI","pay-payment":"Payment Options","pay-messaging":"Store Messages","pay-settings":"Store Server"},R={admin:{users:!0,team:!0,deposits:!0,withdrawals:!0,"settings-wallet":!0,"settings-auth":!0,"settings-messaging":!0,"settings-credits":!0,"settings-server":!0,"pay-products":!0,"pay-subscriptions":!0,"pay-transactions":!0,"pay-coupons":!0,"pay-refunds":!0,"pay-storefront":!0,"pay-ai":!0,"pay-payment":!0,"pay-messaging":!0,"pay-settings":!0},member:{users:!1,team:!0,deposits:!1,withdrawals:!1,"settings-wallet":!1,"settings-auth":!1,"settings-messaging":!1,"settings-credits":!1,"settings-server":!1,"pay-products":!1,"pay-subscriptions":!1,"pay-transactions":!1,"pay-coupons":!1,"pay-refunds":!1,"pay-storefront":!1,"pay-ai":!1,"pay-payment":!1,"pay-messaging":!1,"pay-settings":!1}};function _(){const{config:s,authState:t,_internal:a}=A.useCedrosLogin(),{activeOrg:i,role:n}=P.useOrgs(),[o,f]=r.useState(R),[m,h]=r.useState(!1),[l,j]=r.useState(!1),[d,y]=r.useState(null),p=r.useRef(0),c=r.useMemo(()=>new A.ApiClient({baseUrl:s.serverUrl,timeoutMs:s.requestTimeout,retryAttempts:s.retryAttempts,getAccessToken:a?.getAccessToken}),[s.serverUrl,s.requestTimeout,s.retryAttempts,a]),u=r.useRef(c);u.current=c;const g=r.useCallback(async()=>{if(t!=="authenticated"||!i){f(R);return}h(!0),y(null);const w=++p.current;try{const x=await u.current.get("/admin/dashboard-permissions");if(w!==p.current)return;f(x.permissions)}catch(x){if(w!==p.current)return;if(x instanceof Error&&x.message.includes("404"))f(R);else{const v=x instanceof Error?x.message:"Failed to fetch permissions";y({code:"NETWORK_ERROR",message:v}),f(R)}}finally{w===p.current&&h(!1)}},[t,i]),b=r.useCallback(async w=>{if(t!=="authenticated"||!i)throw new Error("Not authenticated");if(n!=="owner")throw new Error("Only owners can modify dashboard permissions");j(!0),y(null);try{await u.current.request({method:"PUT",path:"/admin/dashboard-permissions",body:w}),f(w)}catch(x){const v=x instanceof Error?x.message:"Failed to update permissions";throw y({code:"NETWORK_ERROR",message:v}),new Error(v)}finally{j(!1)}},[t,i,n]),S=r.useCallback(w=>!i||!n||n==="owner"?!0:o[n]?.[w]??!1,[i,n,o]);return r.useEffect(()=>{i?.id&&g()},[i?.id,g]),{permissions:o,canAccess:S,updatePermissions:b,isLoading:m,isUpdating:l,error:d,fetchPermissions:g}}function T({checked:s,onChange:t,disabled:a,label:i}){return e.jsx("button",{type:"button",role:"switch","aria-checked":s,"aria-label":i,disabled:a,className:`cedros-toggle cedros-toggle-sm ${s?"cedros-toggle-on":"cedros-toggle-off"} ${a?"cedros-toggle-disabled":""}`,onClick:()=>!a&&t(!s),children:e.jsx("span",{className:"cedros-toggle-track",children:e.jsx("span",{className:"cedros-toggle-thumb"})})})}function ae({userRole:s}){const{permissions:t,updatePermissions:a,isLoading:i,isUpdating:n,error:o}=_(),{features:f,isLoading:m}=I(),h=r.useRef(null),l=r.useRef(null),j=s==="owner",d=f.cedrosPay,y=r.useCallback(c=>{l.current=c,h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{l.current&&(a(l.current).catch(()=>{}),l.current=null)},500)},[a]);r.useEffect(()=>()=>{h.current&&clearTimeout(h.current)},[]);const p=r.useCallback((c,u,g)=>{const b={...t,[c]:{...t[c],[u]:g}};y(b)},[t,y]);return i||m?e.jsx("div",{className:"cedros-dashboard__section",children:e.jsx("div",{className:"cedros-dashboard__loading",children:"Loading permissions..."})}):j?e.jsxs("div",{className:"cedros-dashboard__section cedros-permissions-section",children:[e.jsxs("div",{className:"cedros-permissions-header",children:[e.jsx("p",{className:"cedros-permissions-description",children:"Configure which dashboard sections each role can access. Owners always have full access."}),o&&e.jsx("div",{className:"cedros-permissions-error",children:o.message}),n&&e.jsx("span",{className:"cedros-permissions-saving",children:"Saving..."})]}),e.jsx("div",{className:"cedros-permissions-matrix",children:e.jsx("table",{className:"cedros-permissions-table",children:e.jsxs("tbody",{children:[e.jsxs("tr",{className:"cedros-permissions-group-header",children:[e.jsx("th",{className:"cedros-permissions-section-header",children:"Cedros Login"}),e.jsx("th",{className:"cedros-permissions-role-header",children:"Admin"}),e.jsx("th",{className:"cedros-permissions-role-header",children:"Member"})]}),re.map(c=>e.jsxs("tr",{className:"cedros-permissions-row",children:[e.jsx("td",{className:"cedros-permissions-section-label",children:E[c]}),e.jsx("td",{className:"cedros-permissions-toggle-cell",children:e.jsx(T,{checked:t.admin[c]??!1,onChange:u=>p("admin",c,u),disabled:n,label:`Admin access to ${E[c]}`})}),e.jsx("td",{className:"cedros-permissions-toggle-cell",children:e.jsx(T,{checked:t.member[c]??!1,onChange:u=>p("member",c,u),disabled:n,label:`Member access to ${E[c]}`})})]},c)),d&&e.jsxs(e.Fragment,{children:[e.jsxs("tr",{className:"cedros-permissions-group-header",children:[e.jsx("th",{className:"cedros-permissions-section-header",children:"Cedros Pay"}),e.jsx("th",{className:"cedros-permissions-role-header",children:"Admin"}),e.jsx("th",{className:"cedros-permissions-role-header",children:"Member"})]}),ne.map(c=>e.jsxs("tr",{className:"cedros-permissions-row",children:[e.jsx("td",{className:"cedros-permissions-section-label",children:E[c]}),e.jsx("td",{className:"cedros-permissions-toggle-cell",children:e.jsx(T,{checked:t.admin[c]??!1,onChange:u=>p("admin",c,u),disabled:n,label:`Admin access to ${E[c]}`})}),e.jsx("td",{className:"cedros-permissions-toggle-cell",children:e.jsx(T,{checked:t.member[c]??!1,onChange:u=>p("member",c,u),disabled:n,label:`Member access to ${E[c]}`})})]},c))]})]})})})]}):e.jsx("div",{className:"cedros-dashboard__section",children:e.jsx("div",{className:"cedros-dashboard__empty",children:"Only organization owners can configure dashboard permissions."})})}exports.InviteForm=K;exports.InviteList=J;exports.MemberList=z;exports.PermissionsSection=ae;exports.useDashboardPermissions=_;exports.useInvites=se;exports.useMembers=Z;exports.useServerFeatures=I;
1
+ "use strict";const e=require("react/jsx-runtime"),r=require("react"),k=require("./LoadingSpinner-d6sSxgQN.cjs"),$=require("./ErrorMessage-CHbYbVi2.cjs"),D=require("./sanitization-Bo_tn-L2.cjs"),q=require("./validation-BuGQrA-K.cjs"),A=require("./useCedrosLogin-DtJorrE7.cjs"),F=require("./useOrgs-CNqfn-fk.cjs"),P=require("./useSystemSettings-B2jY51ob.cjs"),U=["owner","admin","member"];function z({members:s,currentUserId:t,isLoading:a=!1,error:i,canManage:n=!1,canChangeRoles:o=!1,onUpdateRole:h,onRemove:m,className:f=""}){const[l,j]=r.useState("name"),[d,y]=r.useState("asc"),p=u=>{l===u?y(d==="asc"?"desc":"asc"):(j(u),y("asc"))},c=r.useMemo(()=>{const u={owner:0,admin:1,member:2};return[...s].sort((g,b)=>{let S,w;switch(l){case"name":S=(g.user.name||g.user.email||"").toLowerCase(),w=(b.user.name||b.user.email||"").toLowerCase();break;case"role":S=u[g.role]??99,w=u[b.role]??99;break;case"joinedAt":S=new Date(g.joinedAt).getTime(),w=new Date(b.joinedAt).getTime();break;default:return 0}return S<w?d==="asc"?-1:1:S>w?d==="asc"?1:-1:0})},[s,l,d]);return a&&s.length===0?e.jsxs("div",{className:`cedros-member-list cedros-member-list-loading ${f}`,children:[e.jsx(k.LoadingSpinner,{}),e.jsx("span",{children:"Loading members..."})]}):i?e.jsx("div",{className:`cedros-member-list ${f}`,children:e.jsx($.ErrorMessage,{error:i})}):s.length===0?e.jsx("div",{className:`cedros-member-list cedros-member-list-empty ${f}`,children:e.jsx("p",{children:"No members found."})}):e.jsx("div",{className:`cedros-member-list ${f}`,children:e.jsxs("table",{className:"cedros-member-table",children:[e.jsx("thead",{children:e.jsxs("tr",{children:[e.jsx("th",{children:e.jsxs("button",{type:"button",className:`cedros-admin-sort-button ${l==="name"?"cedros-admin-sort-active":""}`,onClick:()=>p("name"),children:["Member"," ",e.jsx("span",{className:"cedros-admin-sort-icon",children:l==="name"?d==="asc"?"↑":"↓":"↕"})]})}),e.jsx("th",{children:e.jsxs("button",{type:"button",className:`cedros-admin-sort-button ${l==="role"?"cedros-admin-sort-active":""}`,onClick:()=>p("role"),children:["Role"," ",e.jsx("span",{className:"cedros-admin-sort-icon",children:l==="role"?d==="asc"?"↑":"↓":"↕"})]})}),e.jsx("th",{children:e.jsxs("button",{type:"button",className:`cedros-admin-sort-button ${l==="joinedAt"?"cedros-admin-sort-active":""}`,onClick:()=>p("joinedAt"),children:["Joined"," ",e.jsx("span",{className:"cedros-admin-sort-icon",children:l==="joinedAt"?d==="asc"?"↑":"↓":"↕"})]})}),(n||o)&&e.jsx("th",{children:"Actions"})]})}),e.jsx("tbody",{children:c.map(u=>e.jsx(B,{member:u,isCurrentUser:u.userId===t,canManage:n,canChangeRoles:o,onUpdateRole:h,onRemove:m},u.id))})]})})}function B({member:s,isCurrentUser:t,canManage:a,canChangeRoles:i,onUpdateRole:n,onRemove:o}){const[h,m]=r.useState(!1),[f,l]=r.useState(s.role),j=r.useCallback(async c=>{if(!(!n||c===s.role)){m(!0);try{await n(s.userId,c),l(c)}catch{l(s.role)}finally{m(!1)}}},[s.userId,s.role,n]),d=r.useCallback(async()=>{if(!(!o||!window.confirm(`Are you sure you want to remove ${s.user.name||s.user.email} from this organization?`))){m(!0);try{await o(s.userId)}finally{m(!1)}}},[s.userId,s.user.name,s.user.email,o]),y=s.role==="owner",p=!t&&!y;return e.jsxs("tr",{className:`cedros-member-row ${t?"cedros-member-row-current":""}`,children:[e.jsxs("td",{className:"cedros-member-info",children:[e.jsx(W,{user:s.user}),e.jsxs("div",{className:"cedros-member-details",children:[e.jsxs("span",{className:"cedros-member-name",children:[s.user.name||"Unknown",t&&e.jsx("span",{className:"cedros-member-you",children:"(you)"})]}),e.jsx("span",{className:"cedros-member-email",children:s.user.email})]})]}),e.jsx("td",{className:"cedros-member-role",children:i&&p&&n?e.jsx("select",{value:f,onChange:c=>j(c.target.value),disabled:h,className:"cedros-role-select",children:U.map(c=>e.jsx("option",{value:c,children:c.charAt(0).toUpperCase()+c.slice(1)},c))}):e.jsx("span",{className:`cedros-role-badge cedros-role-badge-${s.role}`,children:s.role.charAt(0).toUpperCase()+s.role.slice(1)})}),e.jsx("td",{className:"cedros-member-joined",children:H(s.joinedAt)}),(a||i)&&e.jsx("td",{className:"cedros-member-actions",children:a&&p&&o&&e.jsx("button",{type:"button",className:"cedros-button cedros-button-danger cedros-button-sm",onClick:d,disabled:h,"aria-label":`Remove ${s.user.name||s.user.email}`,children:h?e.jsx(k.LoadingSpinner,{size:"sm"}):"Remove"})})]})}function W({user:s}){const t=D.sanitizeImageUrl(s.picture);if(t)return e.jsx("img",{src:t,alt:s.name||s.email||"Member",className:"cedros-member-avatar",referrerPolicy:"no-referrer"});const a=(s.name?.[0]||s.email?.[0]||"?").toUpperCase();return e.jsx("div",{className:"cedros-member-avatar-placeholder",children:a})}function H(s){return new Date(s).toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})}const V=["admin","member"];function K({onSubmit:s,isLoading:t=!1,error:a,availableRoles:i=V,defaultRole:n="member",className:o=""}){const[h,m]=r.useState(""),[f,l]=r.useState(n),[j,d]=r.useState(null),[y,p]=r.useState(!1),c=r.useRef(null),u=r.useRef(!0);r.useEffect(()=>(u.current=!0,()=>{u.current=!1,c.current!==null&&(window.clearTimeout(c.current),c.current=null)}),[]);const g=r.useCallback(async b=>{b.preventDefault(),d(null),p(!1);const S=h.trim();if(!S){d("Email is required");return}if(!q.validateEmail(S)){d("Please enter a valid email address");return}try{await s(S,f),m(""),l(n),p(!0),c.current!==null&&window.clearTimeout(c.current),c.current=window.setTimeout(()=>{u.current&&p(!1),c.current=null},3e3)}catch{}},[h,f,n,s]);return e.jsxs("form",{className:`cedros-invite-form ${o}`,onSubmit:g,children:[(a||j)&&e.jsx($.ErrorMessage,{error:j??a??null}),y&&e.jsxs("div",{className:"cedros-invite-success",role:"status",children:[e.jsx(G,{}),e.jsx("span",{children:"Invitation sent successfully!"})]}),e.jsxs("div",{className:"cedros-invite-form-row",children:[e.jsxs("div",{className:"cedros-form-group cedros-invite-email-group",children:[e.jsx("label",{htmlFor:"invite-email",className:"cedros-form-label",children:"Email Address"}),e.jsx("input",{id:"invite-email",type:"email",className:"cedros-form-input",value:h,onChange:b=>m(b.target.value),placeholder:"colleague@example.com",disabled:t,autoComplete:"email"})]}),e.jsxs("div",{className:"cedros-form-group cedros-invite-role-group",children:[e.jsx("label",{htmlFor:"invite-role",className:"cedros-form-label",children:"Role"}),e.jsx("select",{id:"invite-role",className:"cedros-form-select",value:f,onChange:b=>l(b.target.value),disabled:t,children:i.map(b=>e.jsx("option",{value:b,children:b.charAt(0).toUpperCase()+b.slice(1)},b))})]}),e.jsx("button",{type:"submit",className:"cedros-button cedros-button-primary cedros-invite-submit",disabled:t||!h.trim(),children:t?e.jsx(k.LoadingSpinner,{size:"sm"}):"Send Invite"})]}),e.jsx("p",{className:"cedros-form-hint",children:"The invited user will receive an email with a link to join your organization."})]})}function G(){return e.jsx("svg",{className:"cedros-invite-check",width:"16",height:"16",viewBox:"0 0 16 16",fill:"none",xmlns:"http://www.w3.org/2000/svg",children:e.jsx("path",{d:"M3 8L6 11L13 5",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round"})})}function J({invites:s,isLoading:t=!1,error:a,canManage:i=!1,onCancel:n,onResend:o,className:h=""}){return t&&s.length===0?e.jsxs("div",{className:`cedros-invite-list cedros-invite-list-loading ${h}`,children:[e.jsx(k.LoadingSpinner,{}),e.jsx("span",{children:"Loading invites..."})]}):a?e.jsx("div",{className:`cedros-invite-list ${h}`,children:e.jsx($.ErrorMessage,{error:a})}):s.length===0?e.jsx("div",{className:`cedros-invite-list cedros-invite-list-empty ${h}`,children:e.jsx("p",{children:"No pending invites."})}):e.jsx("div",{className:`cedros-invite-list ${h}`,children:e.jsx("ul",{className:"cedros-invite-items",children:s.map(m=>e.jsx(Y,{invite:m,canManage:i,onCancel:n,onResend:o},m.id))})})}function Y({invite:s,canManage:t,onCancel:a,onResend:i}){const[n,o]=r.useState(!1),[h,m]=r.useState(!1),f=r.useRef(null),l=new Date(s.expiresAt)<new Date,j=r.useCallback(async()=>{if(!(!a||!window.confirm(`Are you sure you want to cancel the invite for ${s.email}?`))){o(!0);try{await a(s.id)}finally{o(!1)}}},[s.id,s.email,a]),d=r.useCallback(async()=>{if(i){o(!0),m(!1);try{await i(s.id),m(!0),f.current!==null&&window.clearTimeout(f.current),f.current=window.setTimeout(()=>{m(!1),f.current=null},3e3)}finally{o(!1)}}},[s.id,i]);return r.useEffect(()=>()=>{f.current!==null&&(window.clearTimeout(f.current),f.current=null)},[]),e.jsxs("li",{className:`cedros-invite-item ${l?"cedros-invite-item-expired":""}`,children:[e.jsxs("div",{className:"cedros-invite-item-info",children:[e.jsxs("div",{className:"cedros-invite-item-main",children:[e.jsx("span",{className:"cedros-invite-item-email",children:s.email}),e.jsx("span",{className:`cedros-role-badge cedros-role-badge-${s.role}`,children:s.role.charAt(0).toUpperCase()+s.role.slice(1)}),l&&e.jsx("span",{className:"cedros-invite-expired-badge",children:"Expired"})]}),e.jsxs("div",{className:"cedros-invite-item-meta",children:[e.jsxs("span",{className:"cedros-invite-item-date",children:["Invited ",M(s.createdAt)]}),!l&&e.jsxs("span",{className:"cedros-invite-item-expires",children:["Expires ",Q(s.expiresAt)]})]})]}),t&&e.jsxs("div",{className:"cedros-invite-item-actions",children:[h&&e.jsx("span",{className:"cedros-invite-resend-success",children:"Sent!"}),i&&!l&&e.jsx("button",{type:"button",className:"cedros-button cedros-button-outline cedros-button-sm",onClick:d,disabled:n,"aria-label":`Resend invite to ${s.email}`,children:n?e.jsx(k.LoadingSpinner,{size:"sm"}):"Resend"}),a&&e.jsx("button",{type:"button",className:"cedros-button cedros-button-danger cedros-button-sm",onClick:j,disabled:n,"aria-label":`Cancel invite for ${s.email}`,children:"Cancel"})]})]})}function M(s){return new Date(s).toLocaleDateString(void 0,{year:"numeric",month:"short",day:"numeric"})}function Q(s){const t=new Date(s),a=new Date,i=t.getTime()-a.getTime(),n=Math.ceil(i/(1e3*60*60*24));return n<0?"expired":n===0?"today":n===1?"tomorrow":n<7?`in ${n} days`:M(s)}class X{client;constructor(t,a,i,n){this.client=new A.ApiClient({baseUrl:t,timeoutMs:a,retryAttempts:i,getAccessToken:n})}async listMembers(t,a=50,i=0){try{const n=await this.client.get(`/orgs/${t}/members?limit=${a}&offset=${i}`);return{members:n.members.map(o=>({id:o.id,userId:o.userId,orgId:t,role:o.role,joinedAt:o.joinedAt,user:{id:o.userId,email:o.email,name:o.name}})),total:n.total}}catch(n){throw A.handleApiError(n,"Failed to list members")}}async updateMemberRole(t,a,i){try{return await this.client.patch(`/orgs/${t}/members/${a}`,i)}catch(n){throw A.handleApiError(n,"Failed to update member role")}}async removeMember(t,a){try{await this.client.delete(`/orgs/${t}/members/${a}`)}catch(i){throw A.handleApiError(i,"Failed to remove member")}}}function Z(s){const{config:t,authState:a,_internal:i}=A.useCedrosLogin(),[n,o]=r.useState([]),[h,m]=r.useState(0),[f,l]=r.useState(!1),[j,d]=r.useState(null),y=r.useRef(void 0),p=r.useRef(0),c=r.useMemo(()=>new X(t.serverUrl,t.requestTimeout,t.retryAttempts,i?.getAccessToken),[t.serverUrl,t.requestTimeout,t.retryAttempts,i]),u=r.useRef(c);u.current=c;const g=r.useCallback(async w=>{if(!s||a!=="authenticated"){o([]),m(0);return}l(!0),d(null);const x=++p.current;try{const{limit:v=50,offset:N=0}=w??{},C=await u.current.listMembers(s,v,N);if(x!==p.current)return;o(C.members),m(C.total)}catch(v){if(x!==p.current)return;d(v)}finally{x===p.current&&l(!1)}},[s,a]);r.useEffect(()=>{if(a!=="authenticated"){y.current=void 0;return}s!==y.current&&(y.current=s,g())},[s,a,g]);const b=r.useCallback(async(w,x)=>{if(!s)throw new Error("No organization selected");l(!0),d(null);try{await u.current.updateMemberRole(s,w,{role:x}),await g()}catch(v){throw d(v),v}finally{l(!1)}},[s,g]),S=r.useCallback(async w=>{if(!s)throw new Error("No organization selected");l(!0),d(null);try{await u.current.removeMember(s,w),await g()}catch(x){throw d(x),x}finally{l(!1)}},[s,g]);return{members:n,total:h,isLoading:f,error:j,fetchMembers:g,updateMemberRole:b,removeMember:S}}class ee{client;constructor(t,a,i,n){this.client=new A.ApiClient({baseUrl:t,timeoutMs:a,retryAttempts:i,getAccessToken:n})}async listInvites(t,a=50,i=0){try{const n=await this.client.get(`/orgs/${t}/invites?limit=${a}&offset=${i}`);return{invites:n.invites.map(o=>({id:o.id,orgId:o.orgId,email:o.email,role:o.role,invitedBy:o.invitedBy,createdAt:o.createdAt,expiresAt:o.expiresAt})),total:n.total}}catch(n){throw A.handleApiError(n,"Failed to list invites")}}async createInvite(t,a){try{return await this.client.post(`/orgs/${t}/invites`,a)}catch(i){throw A.handleApiError(i,"Failed to create invite")}}async cancelInvite(t,a){try{await this.client.delete(`/orgs/${t}/invites/${a}`)}catch(i){throw A.handleApiError(i,"Failed to cancel invite")}}async resendInvite(t,a){try{await this.client.post(`/orgs/${t}/invites/${a}/resend`,{})}catch(i){throw A.handleApiError(i,"Failed to resend invite")}}async acceptInvite(t){try{return await this.client.post("/invites/accept",t)}catch(a){throw A.handleApiError(a,"Failed to accept invite")}}}function se(s){const{config:t,authState:a,_internal:i}=A.useCedrosLogin(),[n,o]=r.useState([]),[h,m]=r.useState(0),[f,l]=r.useState(!1),[j,d]=r.useState(null),y=r.useRef(void 0),p=r.useRef(0),c=r.useMemo(()=>new ee(t.serverUrl,t.requestTimeout,t.retryAttempts,i?.getAccessToken),[t.serverUrl,t.requestTimeout,t.retryAttempts,i]),u=r.useRef(c);u.current=c;const g=r.useCallback(async v=>{if(!s||a!=="authenticated"){o([]),m(0);return}l(!0),d(null);const N=++p.current;try{const{limit:C=50,offset:O=0}=v??{},L=await u.current.listInvites(s,C,O);if(N!==p.current)return;o(L.invites),m(L.total)}catch(C){if(N!==p.current)return;d(C)}finally{N===p.current&&l(!1)}},[s,a]);r.useEffect(()=>{if(a!=="authenticated"){y.current=void 0;return}s!==y.current&&(y.current=s,g())},[s,a,g]);const b=r.useCallback(async(v,N="member")=>{if(!s)throw new Error("No organization selected");l(!0),d(null);try{await u.current.createInvite(s,{email:v,role:N}),await g()}catch(C){throw d(C),C}finally{l(!1)}},[s,g]),S=r.useCallback(async v=>{if(!s)throw new Error("No organization selected");l(!0),d(null);try{await u.current.cancelInvite(s,v),await g()}catch(N){throw d(N),N}finally{l(!1)}},[s,g]),w=r.useCallback(async v=>{if(!s)throw new Error("No organization selected");l(!0),d(null);try{await u.current.resendInvite(s,v)}catch(N){throw d(N),N}finally{l(!1)}},[s]),x=r.useCallback(async v=>{l(!0),d(null);try{return await u.current.acceptInvite({token:v})}catch(N){throw d(N),N}finally{l(!1)}},[]);return{invites:n,total:h,isLoading:f,error:j,fetchInvites:g,createInvite:b,cancelInvite:S,resendInvite:w,acceptInvite:x}}const te={organizations:!1,sso:!1,mfa:!1,mfaRequired:!1,walletSigning:!1,credits:!1,userWithdrawals:!1,cedrosPay:!1};function _(){const{settings:s,isLoading:t,error:a,fetchSettings:i,getValue:n}=P.useSystemSettings(),[o,h]=r.useState(!1);r.useEffect(()=>{o||(i(),h(!0))},[i,o]);const m=r.useCallback(d=>d===void 0?!1:d==="true"||d==="1",[]),f=r.useMemo(()=>Object.keys(s).length===0?te:{organizations:m(n("feature_organizations")),sso:m(n("feature_sso")),mfa:m(n("feature_mfa")),mfaRequired:m(n("security_require_mfa")),walletSigning:m(n("feature_wallet_signing")),credits:m(n("feature_credits")),userWithdrawals:m(n("feature_user_withdrawals")),cedrosPay:m(n("feature_cedros_pay"))},[s,n,m]),l=r.useCallback(async()=>{await i()},[i]),j=r.useCallback(d=>f[d],[f]);return{features:f,isLoading:t,error:a,refetch:l,isEnabled:j}}const re=["users","team","deposits","withdrawals","settings-wallet","settings-auth","settings-messaging","settings-credits","settings-server"],ne=["pay-products","pay-subscriptions","pay-transactions","pay-coupons","pay-refunds","pay-storefront","pay-ai","pay-payment","pay-messaging","pay-settings"],E={users:"Users",team:"Team",deposits:"Deposits",withdrawals:"Withdrawals","settings-wallet":"Wallet Settings","settings-auth":"Auth Settings","settings-messaging":"Messages Settings","settings-credits":"Credits Settings","settings-server":"Server Settings","pay-products":"Products","pay-subscriptions":"Subscriptions","pay-transactions":"Transactions","pay-coupons":"Coupons","pay-refunds":"Refunds","pay-storefront":"Storefront","pay-ai":"Store AI","pay-payment":"Payment Options","pay-messaging":"Store Messages","pay-settings":"Store Server"},R={admin:{users:!0,team:!0,deposits:!0,withdrawals:!0,"settings-wallet":!0,"settings-auth":!0,"settings-messaging":!0,"settings-credits":!0,"settings-server":!0,"pay-products":!0,"pay-subscriptions":!0,"pay-transactions":!0,"pay-coupons":!0,"pay-refunds":!0,"pay-storefront":!0,"pay-ai":!0,"pay-payment":!0,"pay-messaging":!0,"pay-settings":!0},member:{users:!1,team:!0,deposits:!1,withdrawals:!1,"settings-wallet":!1,"settings-auth":!1,"settings-messaging":!1,"settings-credits":!1,"settings-server":!1,"pay-products":!1,"pay-subscriptions":!1,"pay-transactions":!1,"pay-coupons":!1,"pay-refunds":!1,"pay-storefront":!1,"pay-ai":!1,"pay-payment":!1,"pay-messaging":!1,"pay-settings":!1}};function I(){const{config:s,authState:t,_internal:a}=A.useCedrosLogin(),{activeOrg:i,role:n}=F.useOrgs(),[o,h]=r.useState(R),[m,f]=r.useState(!1),[l,j]=r.useState(!1),[d,y]=r.useState(null),p=r.useRef(0),c=r.useMemo(()=>new A.ApiClient({baseUrl:s.serverUrl,timeoutMs:s.requestTimeout,retryAttempts:s.retryAttempts,getAccessToken:a?.getAccessToken}),[s.serverUrl,s.requestTimeout,s.retryAttempts,a]),u=r.useRef(c);u.current=c;const g=r.useCallback(async()=>{if(t!=="authenticated"||!i){h(R);return}f(!0),y(null);const w=++p.current;try{const x=await u.current.get("/admin/dashboard-permissions");if(w!==p.current)return;h(x.permissions)}catch(x){if(w!==p.current)return;if(x instanceof Error&&x.message.includes("404"))h(R);else{const v=x instanceof Error?x.message:"Failed to fetch permissions";y({code:"NETWORK_ERROR",message:v}),h(R)}}finally{w===p.current&&f(!1)}},[t,i]),b=r.useCallback(async w=>{if(t!=="authenticated"||!i)throw new Error("Not authenticated");if(n!=="owner")throw new Error("Only owners can modify dashboard permissions");j(!0),y(null);try{await u.current.request({method:"PUT",path:"/admin/dashboard-permissions",body:w}),h(w)}catch(x){const v=x instanceof Error?x.message:"Failed to update permissions";throw y({code:"NETWORK_ERROR",message:v}),new Error(v)}finally{j(!1)}},[t,i,n]),S=r.useCallback(w=>!i||!n||n==="owner"?!0:o[n]?.[w]??!1,[i,n,o]);return r.useEffect(()=>{i?.id&&g()},[i?.id,g]),{permissions:o,canAccess:S,updatePermissions:b,isLoading:m,isUpdating:l,error:d,fetchPermissions:g}}function T({checked:s,onChange:t,disabled:a,label:i}){return e.jsx("button",{type:"button",role:"switch","aria-checked":s,"aria-label":i,disabled:a,className:`cedros-toggle cedros-toggle-sm ${s?"cedros-toggle-on":"cedros-toggle-off"} ${a?"cedros-toggle-disabled":""}`,onClick:()=>!a&&t(!s),children:e.jsx("span",{className:"cedros-toggle-track",children:e.jsx("span",{className:"cedros-toggle-thumb"})})})}function ae({userRole:s}){const{permissions:t,updatePermissions:a,isLoading:i,isUpdating:n,error:o}=I(),{features:h,isLoading:m}=_(),f=r.useRef(null),l=r.useRef(null),j=s==="owner",d=h.cedrosPay,y=r.useCallback(c=>{l.current=c,f.current&&clearTimeout(f.current),f.current=setTimeout(()=>{l.current&&(a(l.current).catch(()=>{}),l.current=null)},500)},[a]);r.useEffect(()=>()=>{f.current&&clearTimeout(f.current)},[]);const p=r.useCallback((c,u,g)=>{const b={...t,[c]:{...t[c],[u]:g}};y(b)},[t,y]);return i||m?e.jsx("div",{className:"cedros-dashboard__section",children:e.jsx("div",{className:"cedros-dashboard__loading",children:"Loading permissions..."})}):j?e.jsxs("div",{className:"cedros-dashboard__section cedros-permissions-section",children:[e.jsxs("div",{className:"cedros-permissions-header",children:[e.jsx("p",{className:"cedros-permissions-description",children:"Configure which dashboard sections each role can access. Owners always have full access."}),o&&e.jsx("div",{className:"cedros-permissions-error",children:o.message}),n&&e.jsx("span",{className:"cedros-permissions-saving",children:"Saving..."})]}),e.jsx("div",{className:"cedros-permissions-matrix",children:e.jsx("table",{className:"cedros-permissions-table",children:e.jsxs("tbody",{children:[e.jsxs("tr",{className:"cedros-permissions-group-header",children:[e.jsx("th",{className:"cedros-permissions-section-header",children:"Cedros Login"}),e.jsx("th",{className:"cedros-permissions-role-header",children:"Admin"}),e.jsx("th",{className:"cedros-permissions-role-header",children:"Member"})]}),re.map(c=>e.jsxs("tr",{className:"cedros-permissions-row",children:[e.jsx("td",{className:"cedros-permissions-section-label",children:E[c]}),e.jsx("td",{className:"cedros-permissions-toggle-cell",children:e.jsx(T,{checked:t.admin[c]??!1,onChange:u=>p("admin",c,u),disabled:n,label:`Admin access to ${E[c]}`})}),e.jsx("td",{className:"cedros-permissions-toggle-cell",children:e.jsx(T,{checked:t.member[c]??!1,onChange:u=>p("member",c,u),disabled:n,label:`Member access to ${E[c]}`})})]},c)),d&&e.jsxs(e.Fragment,{children:[e.jsxs("tr",{className:"cedros-permissions-group-header",children:[e.jsx("th",{className:"cedros-permissions-section-header",children:"Cedros Pay"}),e.jsx("th",{className:"cedros-permissions-role-header",children:"Admin"}),e.jsx("th",{className:"cedros-permissions-role-header",children:"Member"})]}),ne.map(c=>e.jsxs("tr",{className:"cedros-permissions-row",children:[e.jsx("td",{className:"cedros-permissions-section-label",children:E[c]}),e.jsx("td",{className:"cedros-permissions-toggle-cell",children:e.jsx(T,{checked:t.admin[c]??!1,onChange:u=>p("admin",c,u),disabled:n,label:`Admin access to ${E[c]}`})}),e.jsx("td",{className:"cedros-permissions-toggle-cell",children:e.jsx(T,{checked:t.member[c]??!1,onChange:u=>p("member",c,u),disabled:n,label:`Member access to ${E[c]}`})})]},c))]})]})})})]}):e.jsx("div",{className:"cedros-dashboard__section",children:e.jsx("div",{className:"cedros-dashboard__empty",children:"Only organization owners can configure dashboard permissions."})})}exports.InviteForm=K;exports.InviteList=J;exports.MemberList=z;exports.PermissionsSection=ae;exports.useDashboardPermissions=I;exports.useInvites=se;exports.useMembers=Z;exports.useServerFeatures=_;