@cedros/login-react 0.0.41 → 0.0.43

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 (128) hide show
  1. package/dist/{AuthenticationSettings-CSoFp-_2.js → AuthenticationSettings-CxAubcoz.js} +1 -1
  2. package/dist/{AuthenticationSettings-CSoFp-_2.js.map → AuthenticationSettings-CxAubcoz.js.map} +1 -1
  3. package/dist/{AuthenticationSettings-Cu5Z2mTC.cjs → AuthenticationSettings-DPr882lj.cjs} +1 -1
  4. package/dist/{AuthenticationSettings-Cu5Z2mTC.cjs.map → AuthenticationSettings-DPr882lj.cjs.map} +1 -1
  5. package/dist/{AuthenticationSettings-DABzZHuI.cjs → AuthenticationSettings-Y40T1djV.cjs} +1 -1
  6. package/dist/{AuthenticationSettings-DABzZHuI.cjs.map → AuthenticationSettings-Y40T1djV.cjs.map} +1 -1
  7. package/dist/{AuthenticationSettings-D4ExU-2a.js → AuthenticationSettings-aVBFKKZ-.js} +1 -1
  8. package/dist/{AuthenticationSettings-D4ExU-2a.js.map → AuthenticationSettings-aVBFKKZ-.js.map} +1 -1
  9. package/dist/AutosaveStatus-ByD01ENa.cjs +1 -0
  10. package/dist/AutosaveStatus-ByD01ENa.cjs.map +1 -0
  11. package/dist/{AutosaveStatus-DMjvXzP2.js → AutosaveStatus-DtF_58rC.js} +608 -279
  12. package/dist/AutosaveStatus-DtF_58rC.js.map +1 -0
  13. package/dist/{CreditSystemSettings-BjQdysRS.js → CreditSystemSettings-BQek2Ux2.js} +1 -1
  14. package/dist/{CreditSystemSettings-BjQdysRS.js.map → CreditSystemSettings-BQek2Ux2.js.map} +1 -1
  15. package/dist/{CreditSystemSettings-DfSfQVE8.cjs → CreditSystemSettings-CbuCce29.cjs} +1 -1
  16. package/dist/{CreditSystemSettings-DfSfQVE8.cjs.map → CreditSystemSettings-CbuCce29.cjs.map} +1 -1
  17. package/dist/{CreditSystemSettings-BWuiRTtA.cjs → CreditSystemSettings-DHG_jhz9.cjs} +1 -1
  18. package/dist/{CreditSystemSettings-BWuiRTtA.cjs.map → CreditSystemSettings-DHG_jhz9.cjs.map} +1 -1
  19. package/dist/{CreditSystemSettings-Du3ac0ID.js → CreditSystemSettings-GDKgYc7I.js} +1 -1
  20. package/dist/{CreditSystemSettings-Du3ac0ID.js.map → CreditSystemSettings-GDKgYc7I.js.map} +1 -1
  21. package/dist/{EmailRegisterForm-CMXsa-_r.js → EmailRegisterForm-p2X5QP58.js} +147 -147
  22. package/dist/EmailRegisterForm-p2X5QP58.js.map +1 -0
  23. package/dist/EmailRegisterForm-xFb6MaVA.cjs +1 -0
  24. package/dist/EmailRegisterForm-xFb6MaVA.cjs.map +1 -0
  25. package/dist/{EmailSettings-CswtKXhb.cjs → EmailSettings-Cg4Z7139.cjs} +1 -1
  26. package/dist/{EmailSettings-CswtKXhb.cjs.map → EmailSettings-Cg4Z7139.cjs.map} +1 -1
  27. package/dist/{EmailSettings-BcHo0cqk.cjs → EmailSettings-CjxBg0cE.cjs} +1 -1
  28. package/dist/{EmailSettings-BcHo0cqk.cjs.map → EmailSettings-CjxBg0cE.cjs.map} +1 -1
  29. package/dist/{EmailSettings-CjngJwDS.js → EmailSettings-Ct6nFslP.js} +1 -1
  30. package/dist/{EmailSettings-CjngJwDS.js.map → EmailSettings-Ct6nFslP.js.map} +1 -1
  31. package/dist/{EmailSettings-ASDHfI0K.js → EmailSettings-D2pCqTKC.js} +1 -1
  32. package/dist/{EmailSettings-ASDHfI0K.js.map → EmailSettings-D2pCqTKC.js.map} +1 -1
  33. package/dist/{EmbeddedWalletSettings-CUY_X7Vj.js → EmbeddedWalletSettings-Bus7UyOX.js} +1 -1
  34. package/dist/{EmbeddedWalletSettings-CUY_X7Vj.js.map → EmbeddedWalletSettings-Bus7UyOX.js.map} +1 -1
  35. package/dist/{EmbeddedWalletSettings-BXlboZ9-.cjs → EmbeddedWalletSettings-CfzvFYnn.cjs} +1 -1
  36. package/dist/{EmbeddedWalletSettings-BXlboZ9-.cjs.map → EmbeddedWalletSettings-CfzvFYnn.cjs.map} +1 -1
  37. package/dist/{EmbeddedWalletSettings-CPLbqlxJ.js → EmbeddedWalletSettings-PwFgtGmK.js} +1 -1
  38. package/dist/{EmbeddedWalletSettings-CPLbqlxJ.js.map → EmbeddedWalletSettings-PwFgtGmK.js.map} +1 -1
  39. package/dist/{EmbeddedWalletSettings-BkwIbTkL.cjs → EmbeddedWalletSettings-t0_5poBu.cjs} +1 -1
  40. package/dist/{EmbeddedWalletSettings-BkwIbTkL.cjs.map → EmbeddedWalletSettings-t0_5poBu.cjs.map} +1 -1
  41. package/dist/GoogleLoginButton-2zNTIKMm.cjs +1 -0
  42. package/dist/GoogleLoginButton-2zNTIKMm.cjs.map +1 -0
  43. package/dist/{GoogleLoginButton-qf4A_A3G.js → GoogleLoginButton-C1WNu7W3.js} +41 -40
  44. package/dist/GoogleLoginButton-C1WNu7W3.js.map +1 -0
  45. package/dist/LoadingSpinner-6vml-zwr.js.map +1 -1
  46. package/dist/LoadingSpinner-d6sSxgQN.cjs.map +1 -1
  47. package/dist/{PermissionsSection-BeFhIgQy.js → PermissionsSection-BDDiEfho.js} +81 -77
  48. package/dist/{PermissionsSection-BeFhIgQy.js.map → PermissionsSection-BDDiEfho.js.map} +1 -1
  49. package/dist/PermissionsSection-CSB_Ikj9.cjs +1 -0
  50. package/dist/{PermissionsSection-B-6DJnN8.cjs.map → PermissionsSection-CSB_Ikj9.cjs.map} +1 -1
  51. package/dist/{ServerSettings-BygCxOTY.cjs → ServerSettings-BjLFs_sb.cjs} +1 -1
  52. package/dist/{ServerSettings-BygCxOTY.cjs.map → ServerSettings-BjLFs_sb.cjs.map} +1 -1
  53. package/dist/{ServerSettings-B9PNMse1.js → ServerSettings-COkhan4u.js} +1 -1
  54. package/dist/{ServerSettings-B9PNMse1.js.map → ServerSettings-COkhan4u.js.map} +1 -1
  55. package/dist/{ServerSettings-BLoWX7KG.js → ServerSettings-D7WJDTbZ.js} +1 -1
  56. package/dist/{ServerSettings-BLoWX7KG.js.map → ServerSettings-D7WJDTbZ.js.map} +1 -1
  57. package/dist/{ServerSettings-CgBdYspU.cjs → ServerSettings-Dmw2rpFA.cjs} +1 -1
  58. package/dist/{ServerSettings-CgBdYspU.cjs.map → ServerSettings-Dmw2rpFA.cjs.map} +1 -1
  59. package/dist/SolanaLoginButton-CqdzSSeJ.cjs +1 -0
  60. package/dist/SolanaLoginButton-CqdzSSeJ.cjs.map +1 -0
  61. package/dist/{SolanaLoginButton-B04dib6X.js → SolanaLoginButton-CyeX35eU.js} +41 -40
  62. package/dist/SolanaLoginButton-CyeX35eU.js.map +1 -0
  63. package/dist/{TeamSection-DbSYDRdI.js → TeamSection-BhsBEckR.js} +1 -1
  64. package/dist/{TeamSection-DbSYDRdI.js.map → TeamSection-BhsBEckR.js.map} +1 -1
  65. package/dist/{TeamSection-B1t1tU-_.cjs → TeamSection-DLxtRmta.cjs} +1 -1
  66. package/dist/{TeamSection-B1t1tU-_.cjs.map → TeamSection-DLxtRmta.cjs.map} +1 -1
  67. package/dist/{UsersSection-C7aRNkK2.cjs → UsersSection-BEKfbhQ4.cjs} +1 -1
  68. package/dist/{UsersSection-C7aRNkK2.cjs.map → UsersSection-BEKfbhQ4.cjs.map} +1 -1
  69. package/dist/{UsersSection--PAE1XRh.js → UsersSection-DbGkmxty.js} +1 -1
  70. package/dist/{UsersSection--PAE1XRh.js.map → UsersSection-DbGkmxty.js.map} +1 -1
  71. package/dist/{WebhookSettings-C-7Yxueu.js → WebhookSettings-CpPvGmV7.js} +1 -1
  72. package/dist/{WebhookSettings-C-7Yxueu.js.map → WebhookSettings-CpPvGmV7.js.map} +1 -1
  73. package/dist/{WebhookSettings-C923ZSKa.js → WebhookSettings-DEHV2ptf.js} +1 -1
  74. package/dist/{WebhookSettings-C923ZSKa.js.map → WebhookSettings-DEHV2ptf.js.map} +1 -1
  75. package/dist/{WebhookSettings-CbU3cfTJ.cjs → WebhookSettings-DbyPJ8V2.cjs} +1 -1
  76. package/dist/{WebhookSettings-CbU3cfTJ.cjs.map → WebhookSettings-DbyPJ8V2.cjs.map} +1 -1
  77. package/dist/{WebhookSettings-D19u9Uok.cjs → WebhookSettings-Rq_nNJuw.cjs} +1 -1
  78. package/dist/{WebhookSettings-D19u9Uok.cjs.map → WebhookSettings-Rq_nNJuw.cjs.map} +1 -1
  79. package/dist/admin-only.cjs +1 -1
  80. package/dist/admin-only.js +1 -1
  81. package/dist/email-only.cjs +1 -1
  82. package/dist/email-only.d.ts +6 -0
  83. package/dist/email-only.js +2 -2
  84. package/dist/google-only.cjs +1 -1
  85. package/dist/google-only.d.ts +6 -0
  86. package/dist/google-only.js +2 -2
  87. package/dist/index.cjs +13 -13
  88. package/dist/index.cjs.map +1 -1
  89. package/dist/index.d.ts +500 -1
  90. package/dist/index.js +5656 -4205
  91. package/dist/index.js.map +1 -1
  92. package/dist/{plugin-BiftIhZe.js → plugin-Bwwe7_ZO.js} +3 -2
  93. package/dist/plugin-Bwwe7_ZO.js.map +1 -0
  94. package/dist/plugin-C4bijrSr.cjs +1 -0
  95. package/dist/plugin-C4bijrSr.cjs.map +1 -0
  96. package/dist/solana-only.cjs +1 -1
  97. package/dist/solana-only.d.ts +6 -0
  98. package/dist/solana-only.js +2 -2
  99. package/dist/useAuth-B1yS_YiD.cjs +1 -0
  100. package/dist/{useAuth-U5CYsHEU.cjs.map → useAuth-B1yS_YiD.cjs.map} +1 -1
  101. package/dist/{useAuth-C-Vw-ggy.js → useAuth-l-itM5am.js} +440 -433
  102. package/dist/{useAuth-C-Vw-ggy.js.map → useAuth-l-itM5am.js.map} +1 -1
  103. package/dist/useUsersStatsSummary-9HQDKBU5.js +1879 -0
  104. package/dist/useUsersStatsSummary-9HQDKBU5.js.map +1 -0
  105. package/dist/useUsersStatsSummary-DiRC8sGs.cjs +1 -0
  106. package/dist/useUsersStatsSummary-DiRC8sGs.cjs.map +1 -0
  107. package/package.json +1 -1
  108. package/dist/AutosaveStatus-B1A1zORa.cjs +0 -1
  109. package/dist/AutosaveStatus-B1A1zORa.cjs.map +0 -1
  110. package/dist/AutosaveStatus-DMjvXzP2.js.map +0 -1
  111. package/dist/EmailRegisterForm-CMXsa-_r.js.map +0 -1
  112. package/dist/EmailRegisterForm-i7f4St2N.cjs +0 -1
  113. package/dist/EmailRegisterForm-i7f4St2N.cjs.map +0 -1
  114. package/dist/GoogleLoginButton-JtRViYWS.cjs +0 -1
  115. package/dist/GoogleLoginButton-JtRViYWS.cjs.map +0 -1
  116. package/dist/GoogleLoginButton-qf4A_A3G.js.map +0 -1
  117. package/dist/PermissionsSection-B-6DJnN8.cjs +0 -1
  118. package/dist/SolanaLoginButton-B04dib6X.js.map +0 -1
  119. package/dist/SolanaLoginButton-nSJHVFpZ.cjs +0 -1
  120. package/dist/SolanaLoginButton-nSJHVFpZ.cjs.map +0 -1
  121. package/dist/plugin-BiftIhZe.js.map +0 -1
  122. package/dist/plugin-BtQdI_Ay.cjs +0 -1
  123. package/dist/plugin-BtQdI_Ay.cjs.map +0 -1
  124. package/dist/useAuth-U5CYsHEU.cjs +0 -1
  125. package/dist/useUsersStatsSummary-5DJwzntC.js +0 -1246
  126. package/dist/useUsersStatsSummary-5DJwzntC.js.map +0 -1
  127. package/dist/useUsersStatsSummary-DgKaUIfs.cjs +0 -1
  128. package/dist/useUsersStatsSummary-DgKaUIfs.cjs.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useUsersStatsSummary-DiRC8sGs.cjs","sources":["../src/utils/adminUserApi.ts","../src/hooks/useAdminUsers.ts","../src/components/admin/AdminUserList.tsx","../src/components/admin/AdminUserDetail.tsx","../src/components/admin/hooks/useUsersStatsSummary.ts"],"sourcesContent":["import type {\n AdminReferredUsersResponse,\n AdminUser,\n AdminUserChatsResponse,\n AdminUserCreditsResponse,\n AdminUserKycResponse,\n AdminUserStatsResponse,\n AdjustCreditsRequest,\n ListAdminUsersResponse,\n ListUsersParams,\n UpdateUserRequest,\n} from '../types';\nimport type { AdminUserAccreditationResponse } from '../types/accreditation';\nimport type {\n AdminDepositListResponse,\n AdminUserWithdrawalHistoryResponse,\n} from '../types/deposit';\nimport { ApiClient, handleApiError } from './apiClient';\n\n/**\n * API client for admin user operations\n *\n * Requires system admin privileges.\n */\nexport class AdminUserApiClient {\n private client: ApiClient;\n\n constructor(\n baseUrl: string,\n timeoutMs?: number,\n retryAttempts?: number,\n getAccessToken?: () => string | null\n ) {\n this.client = new ApiClient({ baseUrl, timeoutMs, retryAttempts, getAccessToken });\n }\n\n /**\n * List all users in the system\n */\n async listUsers(params?: ListUsersParams): Promise<ListAdminUsersResponse> {\n try {\n const query = new URLSearchParams();\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.offset) query.set('offset', String(params.offset));\n const queryString = query.toString();\n const url = `/admin/users${queryString ? `?${queryString}` : ''}`;\n return await this.client.get<ListAdminUsersResponse>(url);\n } catch (error) {\n throw handleApiError(error, 'Failed to list users');\n }\n }\n\n /**\n * Get a specific user by ID\n */\n async getUser(userId: string): Promise<AdminUser> {\n try {\n return await this.client.get<AdminUser>(`/admin/users/${userId}`);\n } catch (error) {\n throw handleApiError(error, 'Failed to get user');\n }\n }\n\n /**\n * Set a user's system admin status\n */\n async setSystemAdmin(userId: string, isAdmin: boolean): Promise<void> {\n try {\n await this.client.patch(`/admin/users/${userId}/system-admin`, { isAdmin });\n } catch (error) {\n throw handleApiError(error, 'Failed to update system admin status');\n }\n }\n\n /**\n * Update a user's profile\n */\n async updateUser(userId: string, data: UpdateUserRequest): Promise<AdminUser> {\n try {\n return await this.client.patch<AdminUser>(`/admin/users/${userId}`, data);\n } catch (error) {\n throw handleApiError(error, 'Failed to update user');\n }\n }\n\n /**\n * Delete a user\n */\n async deleteUser(userId: string): Promise<void> {\n try {\n await this.client.delete(`/admin/users/${userId}`);\n } catch (error) {\n throw handleApiError(error, 'Failed to delete user');\n }\n }\n\n /**\n * Send a password reset email to a user\n */\n async forcePasswordReset(userId: string): Promise<void> {\n try {\n await this.client.post(`/admin/users/${userId}/force-password-reset`, {});\n } catch (error) {\n throw handleApiError(error, 'Failed to send password reset email');\n }\n }\n\n /**\n * Adjust a user's credits\n */\n async adjustCredits(userId: string, data: AdjustCreditsRequest): Promise<void> {\n try {\n await this.client.post(`/admin/users/${userId}/credits`, data);\n } catch (error) {\n throw handleApiError(error, 'Failed to adjust credits');\n }\n }\n\n /**\n * Get a user's deposit history\n */\n async getUserDeposits(\n userId: string,\n params?: ListUsersParams\n ): Promise<AdminDepositListResponse> {\n try {\n const query = new URLSearchParams();\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.offset) query.set('offset', String(params.offset));\n const queryString = query.toString();\n const url = `/admin/users/${userId}/deposits${queryString ? `?${queryString}` : ''}`;\n return await this.client.get<AdminDepositListResponse>(url);\n } catch (error) {\n throw handleApiError(error, 'Failed to get user deposits');\n }\n }\n\n /**\n * Get a user's credit stats and transaction history\n */\n async getUserCredits(\n userId: string,\n params?: ListUsersParams\n ): Promise<AdminUserCreditsResponse> {\n try {\n const query = new URLSearchParams();\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.offset) query.set('offset', String(params.offset));\n const queryString = query.toString();\n const url = `/admin/users/${userId}/credits${queryString ? `?${queryString}` : ''}`;\n return await this.client.get<AdminUserCreditsResponse>(url);\n } catch (error) {\n throw handleApiError(error, 'Failed to get user credits');\n }\n }\n\n /**\n * Get a user's withdrawal history\n */\n async getUserWithdrawalHistory(\n userId: string,\n params?: ListUsersParams\n ): Promise<AdminUserWithdrawalHistoryResponse> {\n try {\n const query = new URLSearchParams();\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.offset) query.set('offset', String(params.offset));\n const queryString = query.toString();\n const url = `/admin/users/${userId}/withdrawal-history${queryString ? `?${queryString}` : ''}`;\n return await this.client.get<AdminUserWithdrawalHistoryResponse>(url);\n } catch (error) {\n throw handleApiError(error, 'Failed to get user withdrawal history');\n }\n }\n\n /**\n * Get a user's chat history (from cedros-pay)\n * Only available when cedros-pay is enabled.\n */\n async getUserChats(userId: string, params?: ListUsersParams): Promise<AdminUserChatsResponse> {\n try {\n const query = new URLSearchParams();\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.offset) query.set('offset', String(params.offset));\n const queryString = query.toString();\n const url = `/admin/users/${userId}/chats${queryString ? `?${queryString}` : ''}`;\n return await this.client.get<AdminUserChatsResponse>(url);\n } catch (error) {\n throw handleApiError(error, 'Failed to get user chat history');\n }\n }\n\n /**\n * Get the list of users directly referred by a given user\n */\n async getUserReferrals(\n userId: string,\n params?: ListUsersParams\n ): Promise<AdminReferredUsersResponse> {\n try {\n const query = new URLSearchParams();\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.offset) query.set('offset', String(params.offset));\n const queryString = query.toString();\n const url = `/admin/users/${userId}/referrals${queryString ? `?${queryString}` : ''}`;\n return await this.client.get<AdminReferredUsersResponse>(url);\n } catch (error) {\n throw handleApiError(error, 'Failed to get user referrals');\n }\n }\n\n /**\n * Get a user's KYC status and session history\n */\n async getUserKyc(userId: string): Promise<AdminUserKycResponse> {\n try {\n return await this.client.get<AdminUserKycResponse>(`/admin/users/${userId}/kyc`);\n } catch (error) {\n throw handleApiError(error, 'Failed to get user KYC data');\n }\n }\n\n /**\n * Override a user's KYC status (system admin only)\n *\n * @param userId - target user ID\n * @param status - new status: \"none\" | \"verified\" | \"failed\"\n */\n async overrideUserKyc(userId: string, status: string): Promise<void> {\n try {\n await this.client.post(`/admin/users/${userId}/kyc/override`, { status });\n } catch (error) {\n throw handleApiError(error, 'Failed to override KYC status');\n }\n }\n\n /**\n * Get a user's accreditation status and submission history\n */\n async getUserAccreditation(userId: string): Promise<AdminUserAccreditationResponse> {\n try {\n return await this.client.get<AdminUserAccreditationResponse>(\n `/admin/users/${userId}/accreditation`\n );\n } catch (error) {\n throw handleApiError(error, 'Failed to get user accreditation data');\n }\n }\n\n /**\n * Review an accreditation submission (approve or reject).\n *\n * @param submissionId - target submission ID\n * @param approved - true to approve, false to reject\n * @param reviewerNotes - optional internal notes\n * @param rejectionReason - required when approved is false\n * @param expiryDays - override default expiry (approve only)\n */\n async reviewAccreditation(\n submissionId: string,\n approved: boolean,\n reviewerNotes?: string,\n rejectionReason?: string,\n expiryDays?: number\n ): Promise<void> {\n try {\n await this.client.post(`/admin/accreditation/${submissionId}/review`, {\n approved,\n reviewerNotes,\n rejectionReason,\n expiryDays,\n });\n } catch (error) {\n throw handleApiError(error, 'Failed to review accreditation submission');\n }\n }\n\n /**\n * Override a user's accreditation status (system admin only).\n *\n * @param userId - target user ID\n * @param status - new status: \"none\" | \"approved\" | \"rejected\"\n */\n async overrideAccreditationStatus(userId: string, status: string): Promise<void> {\n try {\n await this.client.post(`/admin/users/${userId}/accreditation/override`, { status });\n } catch (error) {\n throw handleApiError(error, 'Failed to override accreditation status');\n }\n }\n\n /**\n * Get user statistics by auth method\n */\n async getStats(): Promise<AdminUserStatsResponse> {\n try {\n return await this.client.get<AdminUserStatsResponse>('/admin/users/stats');\n } catch (error) {\n throw handleApiError(error, 'Failed to get user stats');\n }\n }\n}\n","import { useState, useCallback, useMemo } from 'react';\nimport { useCedrosLogin } from '../context/useCedrosLogin';\nimport { AdminUserApiClient } from '../utils/adminUserApi';\nimport type {\n AdminReferredUsersResponse,\n AdminUser,\n AdminUserChatsResponse,\n AdminUserCreditsResponse,\n AdminUserStatsResponse,\n ListAdminUsersResponse,\n ListUsersParams,\n UpdateUserRequest,\n UseAdminUsersReturn,\n} from '../types';\nimport type {\n AdminDepositListResponse,\n AdminUserWithdrawalHistoryResponse,\n} from '../types/deposit';\n\n/**\n * Hook for admin user management operations\n *\n * Provides methods to list all users, get individual users,\n * and manage system admin status. Requires system admin privileges.\n *\n * @example\n * ```tsx\n * function UserManagement() {\n * const { users, total, isLoading, listUsers, setSystemAdmin } = useAdminUsers();\n *\n * useEffect(() => {\n * listUsers({ limit: 20 });\n * }, [listUsers]);\n *\n * return (\n * <AdminUserList\n * users={users}\n * total={total}\n * isLoading={isLoading}\n * onToggleAdmin={(userId, isAdmin) => setSystemAdmin(userId, isAdmin)}\n * />\n * );\n * }\n * ```\n */\nexport function useAdminUsers(): UseAdminUsersReturn {\n const { config, _internal } = useCedrosLogin();\n\n const [users, setUsers] = useState<AdminUser[]>([]);\n const [total, setTotal] = useState(0);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<Error | null>(null);\n const [lastParams, setLastParams] = useState<ListUsersParams>({});\n\n const apiClient = useMemo(\n () =>\n new AdminUserApiClient(\n config.serverUrl,\n config.requestTimeout,\n config.retryAttempts,\n _internal?.getAccessToken\n ),\n [config.serverUrl, config.requestTimeout, config.retryAttempts, _internal]\n );\n\n const listUsers = useCallback(\n async (params?: ListUsersParams): Promise<ListAdminUsersResponse> => {\n setIsLoading(true);\n setError(null);\n setLastParams(params || {});\n\n try {\n const response = await apiClient.listUsers(params);\n setUsers(response.users);\n setTotal(response.total);\n return response;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to list users');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const getUser = useCallback(\n async (userId: string): Promise<AdminUser> => {\n setIsLoading(true);\n setError(null);\n\n try {\n return await apiClient.getUser(userId);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to get user');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const setSystemAdmin = useCallback(\n async (userId: string, isAdmin: boolean): Promise<void> => {\n setIsLoading(true);\n setError(null);\n\n try {\n await apiClient.setSystemAdmin(userId, isAdmin);\n // Update local state\n setUsers((prev) =>\n prev.map((user) => (user.id === userId ? { ...user, isSystemAdmin: isAdmin } : user))\n );\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to update admin status');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const updateUser = useCallback(\n async (userId: string, data: UpdateUserRequest): Promise<AdminUser> => {\n setIsLoading(true);\n setError(null);\n\n try {\n const updated = await apiClient.updateUser(userId, data);\n // Update local state\n setUsers((prev) => prev.map((user) => (user.id === userId ? updated : user)));\n return updated;\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to update user');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const deleteUser = useCallback(\n async (userId: string): Promise<void> => {\n setIsLoading(true);\n setError(null);\n\n try {\n await apiClient.deleteUser(userId);\n // Remove from local state\n setUsers((prev) => prev.filter((user) => user.id !== userId));\n setTotal((prev) => prev - 1);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to delete user');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const forcePasswordReset = useCallback(\n async (userId: string): Promise<void> => {\n setIsLoading(true);\n setError(null);\n\n try {\n await apiClient.forcePasswordReset(userId);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to send password reset');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const adjustCredits = useCallback(\n async (userId: string, amount: number, reason: string): Promise<void> => {\n setIsLoading(true);\n setError(null);\n\n try {\n await apiClient.adjustCredits(userId, { amount, reason });\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to adjust credits');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const getUserDeposits = useCallback(\n async (userId: string, params?: ListUsersParams): Promise<AdminDepositListResponse> => {\n setIsLoading(true);\n setError(null);\n\n try {\n return await apiClient.getUserDeposits(userId, params);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to get user deposits');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const getUserCredits = useCallback(\n async (userId: string, params?: ListUsersParams): Promise<AdminUserCreditsResponse> => {\n setIsLoading(true);\n setError(null);\n\n try {\n return await apiClient.getUserCredits(userId, params);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to get user credits');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const getUserWithdrawalHistory = useCallback(\n async (\n userId: string,\n params?: ListUsersParams\n ): Promise<AdminUserWithdrawalHistoryResponse> => {\n setIsLoading(true);\n setError(null);\n\n try {\n return await apiClient.getUserWithdrawalHistory(userId, params);\n } catch (err) {\n const error =\n err instanceof Error ? err : new Error('Failed to get user withdrawal history');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const getUserChats = useCallback(\n async (userId: string, params?: ListUsersParams): Promise<AdminUserChatsResponse> => {\n setIsLoading(true);\n setError(null);\n\n try {\n return await apiClient.getUserChats(userId, params);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to get user chat history');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const getUserReferrals = useCallback(\n async (userId: string, params?: ListUsersParams): Promise<AdminReferredUsersResponse> => {\n setIsLoading(true);\n setError(null);\n\n try {\n return await apiClient.getUserReferrals(userId, params);\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to get user referrals');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n },\n [apiClient]\n );\n\n const getStats = useCallback(async (): Promise<AdminUserStatsResponse> => {\n setIsLoading(true);\n setError(null);\n\n try {\n return await apiClient.getStats();\n } catch (err) {\n const error = err instanceof Error ? err : new Error('Failed to get user stats');\n setError(error);\n throw error;\n } finally {\n setIsLoading(false);\n }\n }, [apiClient]);\n\n const refresh = useCallback(async () => {\n await listUsers(lastParams);\n }, [listUsers, lastParams]);\n\n const clearError = useCallback(() => {\n setError(null);\n }, []);\n\n return {\n users,\n total,\n isLoading,\n error,\n listUsers,\n getUser,\n setSystemAdmin,\n updateUser,\n deleteUser,\n forcePasswordReset,\n adjustCredits,\n getUserDeposits,\n getUserCredits,\n getUserWithdrawalHistory,\n getUserChats,\n getUserReferrals,\n getStats,\n refresh,\n clearError,\n };\n}\n","/**\n * Admin user list component\n *\n * Displays all registered users in the system with management actions.\n * Requires system admin privileges.\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useAdminUsers } from '../../hooks/useAdminUsers';\nimport type { AdminUser, ListAdminUsersResponse } from '../../types';\n\ntype SortField = 'name' | 'createdAt' | 'lastLoginAt' | 'balanceLamports';\ntype SortOrder = 'asc' | 'desc';\n\nexport interface AdminUserListProps {\n /** Number of items per page (default: 20) */\n pageSize?: number;\n /** Auto-refresh interval in milliseconds (0 to disable) */\n refreshInterval?: number;\n /** Current user's ID (to highlight current user) */\n currentUserId?: string;\n /** Additional CSS classes */\n className?: string;\n /** Callback when list is loaded */\n onLoad?: (response: ListAdminUsersResponse) => void;\n /** Callback when a user is clicked */\n onUserClick?: (user: AdminUser) => void;\n}\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString);\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n}\n\nfunction truncateId(id: string): string {\n if (id.length <= 12) return id;\n return `${id.slice(0, 6)}...${id.slice(-4)}`;\n}\n\nfunction formatBalance(lamports: number | undefined): string {\n if (lamports === undefined || lamports === null) return '-';\n // Convert lamports to SOL (1 SOL = 1,000,000,000 lamports)\n const sol = lamports / 1_000_000_000;\n return sol.toFixed(4);\n}\n\n/**\n * Admin user list display\n *\n * Shows all registered users.\n */\nexport function AdminUserList({\n pageSize = 20,\n refreshInterval = 0,\n currentUserId,\n className = '',\n onLoad,\n onUserClick,\n}: AdminUserListProps) {\n const { users, total, isLoading, error, listUsers, clearError } = useAdminUsers();\n\n const [offset, setOffset] = useState(0);\n const [loadError, setLoadError] = useState<string | null>(null);\n const [sortField, setSortField] = useState<SortField>('createdAt');\n const [sortOrder, setSortOrder] = useState<SortOrder>('desc');\n\n const toggleSort = (field: SortField) => {\n if (sortField === field) {\n setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');\n } else {\n setSortField(field);\n setSortOrder('desc');\n }\n };\n\n // P-05: Client-side sort applies only to the current page of results.\n // For cross-page sorting, add server-side ORDER BY with sort parameters.\n const sortedUsers = useMemo(() => {\n return [...users].sort((a, b) => {\n let aVal: string | number | null;\n let bVal: string | number | null;\n\n switch (sortField) {\n case 'name':\n aVal = (a.name || a.email || '').toLowerCase();\n bVal = (b.name || b.email || '').toLowerCase();\n break;\n case 'createdAt':\n aVal = new Date(a.createdAt).getTime();\n bVal = new Date(b.createdAt).getTime();\n break;\n case 'lastLoginAt':\n aVal = a.lastLoginAt ? new Date(a.lastLoginAt).getTime() : 0;\n bVal = b.lastLoginAt ? new Date(b.lastLoginAt).getTime() : 0;\n break;\n case 'balanceLamports':\n aVal = a.balanceLamports ?? 0;\n bVal = b.balanceLamports ?? 0;\n break;\n default:\n return 0;\n }\n\n if (aVal < bVal) return sortOrder === 'asc' ? -1 : 1;\n if (aVal > bVal) return sortOrder === 'asc' ? 1 : -1;\n return 0;\n });\n }, [users, sortField, sortOrder]);\n\n const fetchUsers = useCallback(async () => {\n try {\n const result = await listUsers({ limit: pageSize, offset });\n onLoad?.(result);\n setLoadError(null);\n } catch (err) {\n setLoadError(err instanceof Error ? err.message : 'Failed to load users');\n }\n }, [pageSize, offset, listUsers, onLoad]);\n\n // Reset offset when page size changes\n useEffect(() => {\n setOffset(0);\n }, [pageSize]);\n\n // Fetch on mount and when dependencies change\n useEffect(() => {\n fetchUsers();\n }, [fetchUsers]);\n\n // Auto-refresh\n useEffect(() => {\n if (refreshInterval <= 0) return;\n\n const interval = setInterval(fetchUsers, refreshInterval);\n return () => clearInterval(interval);\n }, [refreshInterval, fetchUsers]);\n\n const totalPages = Math.ceil(total / pageSize);\n const currentPage = Math.floor(offset / pageSize) + 1;\n\n const goToPage = (page: number) => {\n const newOffset = (page - 1) * pageSize;\n setOffset(Math.max(0, Math.min(newOffset, Math.max(0, total - 1))));\n };\n\n // Error state\n if (loadError || error) {\n return (\n <div className={`cedros-admin-user-list cedros-admin-user-list-error ${className}`}>\n <p className=\"cedros-admin-error\">{loadError || error?.message}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline\"\n onClick={() => {\n clearError();\n setLoadError(null);\n fetchUsers();\n }}\n >\n Retry\n </button>\n </div>\n );\n }\n\n // Loading state (initial load only)\n if (isLoading && users.length === 0) {\n return (\n <div className={`cedros-admin-user-list cedros-admin-user-list-loading ${className}`}>\n <span className=\"cedros-admin-loading-indicator\" />\n <span className=\"cedros-admin-loading-text\">Loading users...</span>\n </div>\n );\n }\n\n return (\n <div className={`cedros-admin-user-list ${className}`}>\n <div className=\"cedros-admin-user-list-header\">\n <h4 className=\"cedros-admin-user-list-title\">All Users</h4>\n <div className=\"cedros-admin-user-list-actions\">\n <span className=\"cedros-admin-queue-count\">\n {total} user{total !== 1 ? 's' : ''}\n </span>\n <button\n type=\"button\"\n className=\"cedros-admin__stats-bar-refresh\"\n onClick={fetchUsers}\n disabled={isLoading}\n title=\"Refresh list\"\n aria-label=\"Refresh list\"\n >\n {isLoading ? '...' : '↻'}\n </button>\n </div>\n </div>\n\n {users.length === 0 ? (\n <div className=\"cedros-admin-empty\">\n <p className=\"cedros-admin-empty-message\">No users found.</p>\n </div>\n ) : (\n <>\n <div className=\"cedros-admin-user-table\">\n <div className=\"cedros-admin-user-thead\">\n <div className=\"cedros-admin-user-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'name' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('name')}\n aria-label=\"Sort by user\"\n >\n User{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'name' ? (sortOrder === 'asc' ? '↑' : '↓') : '↕'}\n </span>\n </button>\n </div>\n <div className=\"cedros-admin-user-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'createdAt' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('createdAt')}\n aria-label=\"Sort by registered date\"\n >\n Registered{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'createdAt' ? (sortOrder === 'asc' ? '↑' : '↓') : '↕'}\n </span>\n </button>\n </div>\n <div className=\"cedros-admin-user-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'lastLoginAt' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('lastLoginAt')}\n aria-label=\"Sort by last login\"\n >\n Last Login{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'lastLoginAt' ? (sortOrder === 'asc' ? '↑' : '↓') : '↕'}\n </span>\n </button>\n </div>\n <div className=\"cedros-admin-user-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'balanceLamports' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('balanceLamports')}\n aria-label=\"Sort by balance\"\n >\n Balance{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'balanceLamports' ? (sortOrder === 'asc' ? '↑' : '↓') : '↕'}\n </span>\n </button>\n </div>\n </div>\n {sortedUsers.map((user) => {\n const isCurrentUser = user.id === currentUserId;\n\n return (\n <div\n key={user.id}\n className={`cedros-admin-user-row ${isCurrentUser ? 'cedros-admin-user-row-current' : ''}`}\n onClick={() => onUserClick?.(user)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onUserClick?.(user);\n }\n }}\n role={onUserClick ? 'button' : undefined}\n tabIndex={onUserClick ? 0 : undefined}\n >\n <div className=\"cedros-admin-user-td cedros-admin-user-info\">\n <div className=\"cedros-admin-user-avatar\">\n {user.picture ? (\n <img\n src={user.picture}\n alt={user.name || user.email || 'User'}\n className=\"cedros-admin-user-avatar-img\"\n referrerPolicy=\"no-referrer\"\n />\n ) : (\n <span className=\"cedros-admin-user-avatar-placeholder\">\n {(user.name?.[0] || user.email?.[0] || '?').toUpperCase()}\n </span>\n )}\n </div>\n <div className=\"cedros-admin-user-details\">\n <span className=\"cedros-admin-user-name\">\n {user.name || 'Unknown'}\n {isCurrentUser && <span className=\"cedros-admin-user-you\">(you)</span>}\n </span>\n <span className=\"cedros-admin-user-email\" title={user.email}>\n {user.email || truncateId(user.id)}\n </span>\n </div>\n </div>\n <div className=\"cedros-admin-user-td\">{formatDate(user.createdAt)}</div>\n <div className=\"cedros-admin-user-td\">\n {user.lastLoginAt ? formatDate(user.lastLoginAt) : '-'}\n </div>\n <div className=\"cedros-admin-user-td\">{formatBalance(user.balanceLamports)}</div>\n </div>\n );\n })}\n </div>\n\n {totalPages > 1 && (\n <div className=\"cedros-admin-pagination\">\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={() => goToPage(currentPage - 1)}\n disabled={currentPage <= 1}\n >\n Previous\n </button>\n <span className=\"cedros-admin-page-info\">\n Page {currentPage} of {totalPages} ({total} total)\n </span>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={() => goToPage(currentPage + 1)}\n disabled={currentPage >= totalPages}\n >\n Next\n </button>\n </div>\n )}\n </>\n )}\n </div>\n );\n}\n","/**\n * Admin user detail component\n *\n * Displays detailed information about a specific user including:\n * - Account information (email, auth methods, admin status)\n * - Credit balance and stats\n * - Deposit history\n * - Transaction history\n *\n * Requires system admin privileges.\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useAdminUsers } from '../../hooks/useAdminUsers';\nimport type {\n AdminReferredUsersResponse,\n AdminUser,\n AdminUserCreditsResponse,\n AdminUserChatsResponse,\n AdminChatSession,\n AdminCreditTransactionItem,\n ListUsersParams,\n ReferredUserItem,\n} from '../../types';\nimport type { AdminDepositListResponse, AdminDepositItem } from '../../types/deposit';\nimport type { AdminUserKycResponse, AdminUserKycSession } from '../../types/adminUser';\nimport type {\n AdminUserAccreditationResponse,\n AccreditationSubmissionItem,\n} from '../../types/accreditation';\nimport { AdminUserApiClient } from '../../utils/adminUserApi';\nimport { useCedrosLogin } from '../../context/useCedrosLogin';\n\nexport interface AdminUserDetailProps {\n /** User ID to display */\n userId: string;\n /** Callback when back button is clicked */\n onBack: () => void;\n /** Current user's ID (to prevent self-demotion) */\n currentUserId?: string;\n /** Callback when edit is clicked (parent handles modal) */\n onEditUser?: (user: AdminUser) => void;\n /** Callback when credits adjustment is clicked (parent handles modal) */\n onAdjustCredits?: (user: AdminUser) => void;\n /** Whether cedros-pay is enabled (shows Chats tab) */\n cedrosPayEnabled?: boolean;\n /** Additional CSS classes */\n className?: string;\n}\n\ntype TabId = 'deposits' | 'transactions' | 'chats' | 'referrals' | 'kyc' | 'accreditation';\n\nfunction formatDate(dateString: string): string {\n const date = new Date(dateString);\n return date.toLocaleDateString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n });\n}\n\nfunction formatDateTime(dateString: string): string {\n const date = new Date(dateString);\n return date.toLocaleString(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nfunction formatSol(lamports: number | null | undefined): string {\n if (lamports === null || lamports === undefined) return '—';\n const sol = lamports / 1_000_000_000;\n return `${sol.toFixed(4)} SOL`;\n}\n\nfunction formatCredits(lamports: number | null | undefined): string {\n if (lamports === null || lamports === undefined) return '—';\n // Credits are stored in lamports but displayed as a simple number\n const credits = lamports / 1_000_000_000;\n return credits.toFixed(4);\n}\n\nfunction formatTxType(txType: string): string {\n const typeMap: Record<string, string> = {\n DEPOSIT: 'Deposit',\n SPEND: 'Spend',\n ADJUSTMENT: 'Adjustment',\n REFUND: 'Refund',\n };\n return typeMap[txType.toUpperCase()] || txType;\n}\n\nfunction formatTxDescription(txType: string, referenceType?: string): string {\n if (referenceType) {\n const refMap: Record<string, string> = {\n deposit: 'Credit deposit',\n purchase: 'Purchase',\n api_call: 'API usage',\n subscription: 'Subscription',\n refund: 'Refund',\n bonus: 'Bonus credit',\n promo: 'Promotional credit',\n correction: 'Balance correction',\n };\n return refMap[referenceType.toLowerCase()] || referenceType;\n }\n // Fallback based on tx type\n const typeDescriptions: Record<string, string> = {\n DEPOSIT: 'Credit added',\n SPEND: 'Credit used',\n ADJUSTMENT: 'Manual adjustment',\n REFUND: 'Credit refunded',\n };\n return typeDescriptions[txType.toUpperCase()] || '—';\n}\n\n/**\n * Admin user detail display\n *\n * Shows comprehensive user information with deposit and credit history.\n */\nexport function AdminUserDetail({\n userId,\n onBack,\n currentUserId,\n onEditUser,\n onAdjustCredits,\n cedrosPayEnabled = false,\n className = '',\n}: AdminUserDetailProps) {\n const { config, _internal } = useCedrosLogin();\n const {\n isLoading,\n getUser,\n getUserDeposits,\n getUserCredits,\n getUserChats,\n getUserReferrals,\n deleteUser,\n forcePasswordReset,\n clearError,\n } = useAdminUsers();\n\n const kycApiClient = useMemo(\n () =>\n new AdminUserApiClient(\n config.serverUrl,\n config.requestTimeout,\n config.retryAttempts,\n _internal?.getAccessToken\n ),\n [config.serverUrl, config.requestTimeout, config.retryAttempts, _internal]\n );\n\n const [user, setUser] = useState<AdminUser | null>(null);\n const [credits, setCredits] = useState<AdminUserCreditsResponse | null>(null);\n const [deposits, setDeposits] = useState<AdminDepositListResponse | null>(null);\n const [chats, setChats] = useState<AdminUserChatsResponse | null>(null);\n const [referrals, setReferrals] = useState<AdminReferredUsersResponse | null>(null);\n const [kycData, setKycData] = useState<AdminUserKycResponse | null>(null);\n const [accreditationData, setAccreditationData] =\n useState<AdminUserAccreditationResponse | null>(null);\n const [activeTab, setActiveTab] = useState<TabId>('deposits');\n const [userError, setUserError] = useState<string | null>(null);\n const [creditsError, setCreditsError] = useState<string | null>(null);\n const [depositsError, setDepositsError] = useState<string | null>(null);\n const [chatsError, setChatsError] = useState<string | null>(null);\n const [referralsError, setReferralsError] = useState<string | null>(null);\n const [kycError, setKycError] = useState<string | null>(null);\n const [accreditationError, setAccreditationError] = useState<string | null>(null);\n const [actionInProgress, setActionInProgress] = useState(false);\n\n // Pagination state\n const [depositsOffset, setDepositsOffset] = useState(0);\n const [transactionsOffset, setTransactionsOffset] = useState(0);\n const [chatsOffset, setChatsOffset] = useState(0);\n const [referralsOffset, setReferralsOffset] = useState(0);\n const pageSize = 10;\n\n const fetchUser = useCallback(async () => {\n try {\n const userData = await getUser(userId);\n setUser(userData);\n setUserError(null);\n } catch (err) {\n setUserError(err instanceof Error ? err.message : 'Failed to load user');\n }\n }, [userId, getUser]);\n\n const fetchDeposits = useCallback(async () => {\n try {\n const params: ListUsersParams = { limit: pageSize, offset: depositsOffset };\n const depositsData = await getUserDeposits(userId, params);\n setDeposits(depositsData);\n setDepositsError(null);\n } catch (err) {\n setDepositsError(err instanceof Error ? err.message : 'Failed to load deposits');\n }\n }, [userId, getUserDeposits, depositsOffset]);\n\n const fetchCredits = useCallback(async () => {\n try {\n const params: ListUsersParams = { limit: pageSize, offset: transactionsOffset };\n const creditsData = await getUserCredits(userId, params);\n setCredits(creditsData);\n setCreditsError(null);\n } catch (err) {\n setCreditsError(err instanceof Error ? err.message : 'Failed to load credits');\n }\n }, [userId, getUserCredits, transactionsOffset]);\n\n const fetchChats = useCallback(async () => {\n if (!cedrosPayEnabled) return;\n try {\n const params: ListUsersParams = { limit: pageSize, offset: chatsOffset };\n const chatsData = await getUserChats(userId, params);\n setChats(chatsData);\n setChatsError(null);\n } catch (err) {\n setChatsError(err instanceof Error ? err.message : 'Failed to load chat history');\n }\n }, [userId, getUserChats, chatsOffset, cedrosPayEnabled]);\n\n const fetchReferrals = useCallback(async () => {\n try {\n const params: ListUsersParams = { limit: pageSize, offset: referralsOffset };\n const data = await getUserReferrals(userId, params);\n setReferrals(data);\n setReferralsError(null);\n } catch (err) {\n setReferralsError(err instanceof Error ? err.message : 'Failed to load referrals');\n }\n }, [userId, getUserReferrals, referralsOffset]);\n\n const fetchKyc = useCallback(async () => {\n try {\n const data = await kycApiClient.getUserKyc(userId);\n setKycData(data);\n setKycError(null);\n } catch (err) {\n setKycError(err instanceof Error ? err.message : 'Failed to load KYC data');\n }\n }, [userId, kycApiClient]);\n\n const fetchAccreditation = useCallback(async () => {\n try {\n const data = await kycApiClient.getUserAccreditation(userId);\n setAccreditationData(data);\n setAccreditationError(null);\n } catch (err) {\n setAccreditationError(\n err instanceof Error ? err.message : 'Failed to load accreditation data'\n );\n }\n }, [userId, kycApiClient]);\n\n const handleAccreditationOverride = useCallback(\n async (status: string) => {\n try {\n await kycApiClient.overrideAccreditationStatus(userId, status);\n await fetchAccreditation();\n } catch (err) {\n setAccreditationError(\n err instanceof Error ? err.message : 'Failed to override accreditation status'\n );\n }\n },\n [userId, kycApiClient, fetchAccreditation]\n );\n\n const handleAccreditationReview = useCallback(\n async (\n submissionId: string,\n approved: boolean,\n reviewerNotes?: string,\n rejectionReason?: string\n ) => {\n try {\n await kycApiClient.reviewAccreditation(\n submissionId,\n approved,\n reviewerNotes,\n rejectionReason\n );\n await fetchAccreditation();\n } catch (err) {\n setAccreditationError(\n err instanceof Error ? err.message : 'Failed to review accreditation submission'\n );\n }\n },\n [kycApiClient, fetchAccreditation]\n );\n\n const handleKycOverride = useCallback(\n async (status: string) => {\n try {\n await kycApiClient.overrideUserKyc(userId, status);\n await fetchKyc();\n } catch (err) {\n setKycError(err instanceof Error ? err.message : 'Failed to override KYC status');\n }\n },\n [userId, kycApiClient, fetchKyc]\n );\n\n // Initial load\n useEffect(() => {\n fetchUser();\n fetchDeposits();\n fetchCredits();\n fetchReferrals();\n fetchKyc();\n fetchAccreditation();\n if (cedrosPayEnabled) {\n fetchChats();\n }\n }, [fetchUser, fetchDeposits, fetchCredits, fetchChats, fetchReferrals, fetchKyc, fetchAccreditation, cedrosPayEnabled]);\n\n const handleDelete = async () => {\n if (!user) return;\n if (user.id === currentUserId) {\n alert('You cannot delete your own account');\n return;\n }\n if (user.isSystemAdmin) {\n alert('Cannot delete a system admin. Remove admin status first.');\n return;\n }\n\n const confirmed = window.confirm(\n `Are you sure you want to delete ${user.name || user.email || 'this user'}? This action cannot be undone.`\n );\n if (!confirmed) return;\n\n setActionInProgress(true);\n try {\n await deleteUser(user.id);\n onBack();\n } catch {\n // Error handled by hook\n } finally {\n setActionInProgress(false);\n }\n };\n\n const handlePasswordReset = async () => {\n if (!user?.email) {\n alert('User has no email address');\n return;\n }\n\n const confirmed = window.confirm(`Send a password reset email to ${user.email}?`);\n if (!confirmed) return;\n\n setActionInProgress(true);\n try {\n await forcePasswordReset(user.id);\n alert('Password reset email sent');\n } catch {\n // Error handled by hook\n } finally {\n setActionInProgress(false);\n }\n };\n\n // Pagination handlers\n const depositsTotalPages = deposits ? Math.ceil(deposits.total / pageSize) : 0;\n const depositsCurrentPage = Math.floor(depositsOffset / pageSize) + 1;\n\n const transactionsTotalPages = credits ? Math.ceil(credits.totalTransactions / pageSize) : 0;\n const transactionsCurrentPage = Math.floor(transactionsOffset / pageSize) + 1;\n\n const goToDepositsPage = (page: number) => {\n setDepositsOffset((page - 1) * pageSize);\n };\n\n const goToTransactionsPage = (page: number) => {\n setTransactionsOffset((page - 1) * pageSize);\n };\n\n const chatsTotalPages = chats ? Math.ceil(chats.total / pageSize) : 0;\n const chatsCurrentPage = Math.floor(chatsOffset / pageSize) + 1;\n\n const goToChatsPage = (page: number) => {\n setChatsOffset((page - 1) * pageSize);\n };\n\n const referralsTotalPages = referrals ? Math.ceil(referrals.total / pageSize) : 0;\n const referralsCurrentPage = Math.floor(referralsOffset / pageSize) + 1;\n\n const goToReferralsPage = (page: number) => {\n setReferralsOffset((page - 1) * pageSize);\n };\n\n // Critical error - user fetch failed\n if (userError) {\n return (\n <div className={`cedros-admin-user-detail cedros-admin-user-detail-error ${className}`}>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={onBack}\n >\n Back\n </button>\n <p className=\"cedros-admin-error\">{userError}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline\"\n onClick={() => {\n clearError();\n setUserError(null);\n fetchUser();\n }}\n >\n Retry\n </button>\n </div>\n );\n }\n\n // Loading state\n if (isLoading && !user) {\n return (\n <div className={`cedros-admin-user-detail cedros-admin-user-detail-loading ${className}`}>\n <span className=\"cedros-admin-loading-indicator\" />\n <span className=\"cedros-admin-loading-text\">Loading user...</span>\n </div>\n );\n }\n\n if (!user) {\n return (\n <div className={`cedros-admin-user-detail ${className}`}>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={onBack}\n >\n Back\n </button>\n <p className=\"cedros-admin-empty-message\">User not found.</p>\n </div>\n );\n }\n\n const isCurrentUser = user.id === currentUserId;\n\n return (\n <div className={`cedros-admin-user-detail ${className}`}>\n {/* Header */}\n <div className=\"cedros-admin-user-detail-header\">\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm cedros-admin-back-btn\"\n onClick={onBack}\n >\n Back to Users\n </button>\n <div className=\"cedros-admin-user-detail-actions\">\n {onEditUser && (\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={() => onEditUser(user)}\n disabled={actionInProgress}\n >\n Edit\n </button>\n )}\n {user.email && (\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={handlePasswordReset}\n disabled={actionInProgress}\n >\n Reset Password\n </button>\n )}\n {onAdjustCredits && (\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={() => onAdjustCredits(user)}\n disabled={actionInProgress}\n >\n Adjust Credits\n </button>\n )}\n {!isCurrentUser && !user.isSystemAdmin && (\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm cedros-admin-btn-danger\"\n onClick={handleDelete}\n disabled={actionInProgress}\n >\n Delete\n </button>\n )}\n </div>\n </div>\n\n {/* User Info Section */}\n <div className=\"cedros-admin-user-detail-info\">\n <div className=\"cedros-admin-user-detail-avatar\">\n {user.picture ? (\n <img\n src={user.picture}\n alt={user.name || user.email || 'User'}\n className=\"cedros-admin-user-detail-avatar-img\"\n referrerPolicy=\"no-referrer\"\n />\n ) : (\n <span className=\"cedros-admin-user-detail-avatar-placeholder\">\n {(user.name?.[0] || user.email?.[0] || '?').toUpperCase()}\n </span>\n )}\n </div>\n <div className=\"cedros-admin-user-detail-meta\">\n <h2 className=\"cedros-admin-user-detail-name\">\n {user.name || 'Unknown'}\n {isCurrentUser && <span className=\"cedros-admin-user-you\">(you)</span>}\n </h2>\n <p className=\"cedros-admin-user-detail-email\">\n {user.email || 'No email'}\n {user.emailVerified && (\n <span className=\"cedros-admin-verified-badge\" title=\"Email verified\">\n Verified\n </span>\n )}\n </p>\n {user.isSystemAdmin && (\n <div className=\"cedros-admin-user-detail-badges\">\n <span className=\"cedros-admin-admin-badge cedros-admin-admin-badge-yes\">\n System Admin\n </span>\n </div>\n )}\n <div className=\"cedros-admin-user-detail-methods\">\n <span className=\"cedros-admin-user-detail-methods-label\">Auth Methods:</span>\n {user.authMethods.length > 0 ? (\n user.authMethods.map((method) => (\n <span\n key={method}\n className={`cedros-admin-auth-badge cedros-admin-auth-badge-${method}`}\n >\n {method}\n </span>\n ))\n ) : (\n <span className=\"cedros-admin-auth-badge cedros-admin-auth-badge-none\">none</span>\n )}\n </div>\n <p className=\"cedros-admin-user-detail-dates\">\n Registered: {formatDate(user.createdAt)} | Updated: {formatDate(user.updatedAt)}\n </p>\n {user.referralCode && (\n <div className=\"cedros-admin-user-detail-referral\">\n <span className=\"cedros-admin-user-detail-referral-label\">Referral:</span>\n <span className=\"cedros-admin-user-detail-referral-code\">{user.referralCode}</span>\n {user.referralCount !== undefined && user.referralCount > 0 && (\n <span className=\"cedros-admin-user-detail-referral-count\">\n ({user.referralCount} referred)\n </span>\n )}\n {user.referredBy && (\n <span className=\"cedros-admin-user-detail-referred-by\">\n Referred by:{' '}\n <button\n type=\"button\"\n className=\"cedros-admin-user-uuid-link\"\n onClick={() => navigator.clipboard?.writeText(user.referredBy!)}\n title=\"Click to copy referrer UUID\"\n >\n {user.referredBy}\n </button>\n </span>\n )}\n </div>\n )}\n </div>\n </div>\n\n {/* Stats Cards */}\n {creditsError ? (\n <div className=\"cedros-admin-stats-error\">\n <p className=\"cedros-admin-error-inline\">{creditsError}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={() => {\n setCreditsError(null);\n fetchCredits();\n }}\n >\n Retry\n </button>\n </div>\n ) : credits ? (\n <div className=\"cedros-admin-user-detail-stats\">\n <div className=\"cedros-admin-stat-card\">\n <span className=\"cedros-admin-stat-label\">Credit Balance</span>\n <span className=\"cedros-admin-stat-value\">\n {formatCredits(credits.stats.currentBalanceLamports)}\n </span>\n </div>\n <div className=\"cedros-admin-stat-card\">\n <span className=\"cedros-admin-stat-label\">Total Credited</span>\n <span className=\"cedros-admin-stat-value\">\n {formatCredits(credits.stats.totalDepositedLamports)}\n </span>\n </div>\n <div className=\"cedros-admin-stat-card\">\n <span className=\"cedros-admin-stat-label\">Total Spent</span>\n <span className=\"cedros-admin-stat-value\">\n {formatCredits(credits.stats.totalSpentLamports)}\n </span>\n </div>\n <div className=\"cedros-admin-stat-card\">\n <span className=\"cedros-admin-stat-label\">Deposits</span>\n <span className=\"cedros-admin-stat-value\">{credits.stats.depositCount}</span>\n </div>\n <div className=\"cedros-admin-stat-card\">\n <span className=\"cedros-admin-stat-label\">Transactions</span>\n <span className=\"cedros-admin-stat-value\">{credits.stats.spendCount}</span>\n </div>\n </div>\n ) : (\n <div className=\"cedros-admin-stats-loading\">\n <span className=\"cedros-admin-loading-indicator\" />\n <span>Loading credit stats...</span>\n </div>\n )}\n\n {/* Tabs */}\n <div className=\"cedros-admin-user-detail-tabs\">\n <button\n type=\"button\"\n className={`cedros-admin-tab ${activeTab === 'deposits' ? 'cedros-admin-tab-active' : ''}`}\n onClick={() => setActiveTab('deposits')}\n >\n Deposits ({deposits?.total ?? 0})\n </button>\n <button\n type=\"button\"\n className={`cedros-admin-tab ${activeTab === 'transactions' ? 'cedros-admin-tab-active' : ''}`}\n onClick={() => setActiveTab('transactions')}\n >\n Credits ({credits?.totalTransactions ?? 0})\n </button>\n {cedrosPayEnabled && (\n <button\n type=\"button\"\n className={`cedros-admin-tab ${activeTab === 'chats' ? 'cedros-admin-tab-active' : ''}`}\n onClick={() => setActiveTab('chats')}\n >\n Chats ({chats?.total ?? 0})\n </button>\n )}\n <button\n type=\"button\"\n className={`cedros-admin-tab ${activeTab === 'referrals' ? 'cedros-admin-tab-active' : ''}`}\n onClick={() => setActiveTab('referrals')}\n >\n Referrals ({referrals?.total ?? user.referralCount ?? 0})\n </button>\n <button\n type=\"button\"\n className={`cedros-admin-tab ${activeTab === 'kyc' ? 'cedros-admin-tab-active' : ''}`}\n onClick={() => setActiveTab('kyc')}\n >\n KYC ({kycData?.totalSessions ?? 0})\n </button>\n <button\n type=\"button\"\n className={`cedros-admin-tab ${activeTab === 'accreditation' ? 'cedros-admin-tab-active' : ''}`}\n onClick={() => setActiveTab('accreditation')}\n >\n Accreditation ({accreditationData?.totalSubmissions ?? 0})\n </button>\n </div>\n\n {/* Tab Content */}\n <div className=\"cedros-admin-user-detail-content\">\n {activeTab === 'deposits' && (\n <DepositsTab\n deposits={deposits?.deposits ?? []}\n total={deposits?.total ?? 0}\n currentPage={depositsCurrentPage}\n totalPages={depositsTotalPages}\n onPageChange={goToDepositsPage}\n isLoading={isLoading}\n error={depositsError}\n onRetry={() => {\n setDepositsError(null);\n fetchDeposits();\n }}\n />\n )}\n {activeTab === 'transactions' && (\n <TransactionsTab\n transactions={credits?.transactions ?? []}\n total={credits?.totalTransactions ?? 0}\n currentPage={transactionsCurrentPage}\n totalPages={transactionsTotalPages}\n onPageChange={goToTransactionsPage}\n error={creditsError}\n onRetry={() => {\n setCreditsError(null);\n fetchCredits();\n }}\n isLoading={isLoading}\n />\n )}\n {activeTab === 'chats' && cedrosPayEnabled && (\n <ChatsTab\n sessions={chats?.sessions ?? []}\n total={chats?.total ?? 0}\n currentPage={chatsCurrentPage}\n totalPages={chatsTotalPages}\n onPageChange={goToChatsPage}\n error={chatsError}\n onRetry={() => {\n setChatsError(null);\n fetchChats();\n }}\n isLoading={isLoading}\n />\n )}\n {activeTab === 'referrals' && (\n <ReferralsTab\n referrals={referrals?.users ?? []}\n total={referrals?.total ?? 0}\n currentPage={referralsCurrentPage}\n totalPages={referralsTotalPages}\n onPageChange={goToReferralsPage}\n error={referralsError}\n onRetry={() => {\n setReferralsError(null);\n fetchReferrals();\n }}\n isLoading={isLoading}\n />\n )}\n {activeTab === 'kyc' && (\n <KycTab\n kycData={kycData}\n userKycStatus={user.kycStatus}\n userKycVerifiedAt={user.kycVerifiedAt}\n userKycExpiresAt={user.kycExpiresAt}\n error={kycError}\n onRetry={() => {\n setKycError(null);\n fetchKyc();\n }}\n onOverride={handleKycOverride}\n />\n )}\n {activeTab === 'accreditation' && (\n <AccreditationTab\n accreditationData={accreditationData}\n userAccreditationStatus={user.accreditationStatus}\n userAccreditationVerifiedAt={user.accreditationVerifiedAt}\n userAccreditationExpiresAt={user.accreditationExpiresAt}\n error={accreditationError}\n onRetry={() => {\n setAccreditationError(null);\n fetchAccreditation();\n }}\n onOverride={handleAccreditationOverride}\n onReview={handleAccreditationReview}\n />\n )}\n </div>\n </div>\n );\n}\n\n// =============================================================================\n// Tab Components\n// =============================================================================\n\ninterface DepositsTabProps {\n deposits: AdminDepositItem[];\n total: number;\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n isLoading: boolean;\n error: string | null;\n onRetry: () => void;\n}\n\nfunction DepositsTab({\n deposits,\n total,\n currentPage,\n totalPages,\n onPageChange,\n isLoading,\n error,\n onRetry,\n}: DepositsTabProps) {\n if (error) {\n return (\n <div className=\"cedros-admin-tab-error\">\n <p className=\"cedros-admin-error-inline\">{error}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={onRetry}\n >\n Retry\n </button>\n </div>\n );\n }\n\n if (isLoading && deposits.length === 0) {\n return (\n <div className=\"cedros-admin-tab-loading\">\n <span className=\"cedros-admin-loading-indicator\" />\n <span>Loading deposits...</span>\n </div>\n );\n }\n\n if (total === 0) {\n return <div className=\"cedros-admin-empty-message\">No deposits found.</div>;\n }\n\n return (\n <>\n <div className=\"cedros-admin-list-table\">\n <div className=\"cedros-admin-list-thead\">\n <div className=\"cedros-admin-list-th\">Date</div>\n <div className=\"cedros-admin-list-th\">Amount</div>\n <div className=\"cedros-admin-list-th\">Status</div>\n <div className=\"cedros-admin-list-th\">Transaction</div>\n </div>\n {deposits.map((deposit) => (\n <div key={deposit.id} className=\"cedros-admin-list-row\">\n <div className=\"cedros-admin-list-td\">{formatDateTime(deposit.createdAt)}</div>\n <div className=\"cedros-admin-list-td\">{formatSol(deposit.amountLamports)}</div>\n <div className=\"cedros-admin-list-td\">\n <span className={`cedros-admin-status-badge cedros-admin-status-${deposit.status}`}>\n {deposit.status}\n </span>\n </div>\n <div className=\"cedros-admin-list-td cedros-admin-list-td-actions\">\n {deposit.txSignature ? (\n <>\n <span className=\"cedros-admin-list-td-mono\" title={deposit.txSignature}>\n {deposit.txSignature.slice(0, 8)}...\n </span>\n <a\n href={`https://orbmarkets.io/tx/${deposit.txSignature}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"cedros-admin-icon-link\"\n title=\"View on Orbmarkets\"\n aria-label=\"View transaction on Orbmarkets\"\n >\n ↗\n </a>\n </>\n ) : (\n <span className=\"cedros-admin-list-td-muted\">—</span>\n )}\n </div>\n </div>\n ))}\n </div>\n {totalPages > 1 && (\n <Pagination\n currentPage={currentPage}\n totalPages={totalPages}\n total={total}\n onPageChange={onPageChange}\n />\n )}\n </>\n );\n}\n\ninterface TransactionsTabProps {\n transactions: AdminCreditTransactionItem[];\n total: number;\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n isLoading: boolean;\n error: string | null;\n onRetry: () => void;\n}\n\nfunction TransactionsTab({\n transactions,\n total,\n currentPage,\n totalPages,\n onPageChange,\n isLoading,\n error,\n onRetry,\n}: TransactionsTabProps) {\n if (error) {\n return (\n <div className=\"cedros-admin-tab-error\">\n <p className=\"cedros-admin-error-inline\">{error}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={onRetry}\n >\n Retry\n </button>\n </div>\n );\n }\n\n if (isLoading && transactions.length === 0) {\n return (\n <div className=\"cedros-admin-tab-loading\">\n <span className=\"cedros-admin-loading-indicator\" />\n <span>Loading transactions...</span>\n </div>\n );\n }\n\n if (total === 0) {\n return <div className=\"cedros-admin-empty-message\">No credit transactions found.</div>;\n }\n\n return (\n <>\n <div className=\"cedros-admin-list-table\">\n <div className=\"cedros-admin-list-thead\">\n <div className=\"cedros-admin-list-th\">Date</div>\n <div className=\"cedros-admin-list-th\">Type</div>\n <div className=\"cedros-admin-list-th\">Description</div>\n <div className=\"cedros-admin-list-th\">Amount</div>\n </div>\n {transactions.map((tx) => (\n <div key={tx.id} className=\"cedros-admin-list-row\">\n <div className=\"cedros-admin-list-td\">{formatDateTime(tx.createdAt)}</div>\n <div className=\"cedros-admin-list-td\">\n <span\n className={`cedros-admin-tx-type cedros-admin-tx-type-${tx.txType.toLowerCase()}`}\n >\n {formatTxType(tx.txType)}\n </span>\n </div>\n <div className=\"cedros-admin-list-td\">\n {formatTxDescription(tx.txType, tx.referenceType)}\n </div>\n <div\n className={`cedros-admin-list-td ${tx.amountLamports >= 0 ? 'cedros-admin-amount-positive' : 'cedros-admin-amount-negative'}`}\n >\n {tx.amountLamports >= 0 ? '+' : ''}\n {formatCredits(tx.amountLamports)}\n </div>\n </div>\n ))}\n </div>\n {totalPages > 1 && (\n <Pagination\n currentPage={currentPage}\n totalPages={totalPages}\n total={total}\n onPageChange={onPageChange}\n />\n )}\n </>\n );\n}\n\ninterface ChatsTabProps {\n sessions: AdminChatSession[];\n total: number;\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n isLoading: boolean;\n error: string | null;\n onRetry: () => void;\n}\n\nfunction ChatsTab({\n sessions,\n total,\n currentPage,\n totalPages,\n onPageChange,\n isLoading,\n error,\n onRetry,\n}: ChatsTabProps) {\n if (error) {\n return (\n <div className=\"cedros-admin-tab-error\">\n <p className=\"cedros-admin-error-inline\">{error}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={onRetry}\n >\n Retry\n </button>\n </div>\n );\n }\n\n if (isLoading && sessions.length === 0) {\n return (\n <div className=\"cedros-admin-tab-loading\">\n <span className=\"cedros-admin-loading-indicator\" />\n <span>Loading chat history...</span>\n </div>\n );\n }\n\n if (total === 0) {\n return <div className=\"cedros-admin-empty-message\">No chat sessions found.</div>;\n }\n\n return (\n <>\n <div className=\"cedros-admin-list-table\">\n <div className=\"cedros-admin-list-thead\">\n <div className=\"cedros-admin-list-th\">Date</div>\n <div className=\"cedros-admin-list-th\">Session</div>\n <div className=\"cedros-admin-list-th\">Messages</div>\n </div>\n {sessions.map((session) => (\n <div key={session.id} className=\"cedros-admin-list-row\">\n <div className=\"cedros-admin-list-td\">{formatDateTime(session.createdAt)}</div>\n <div className=\"cedros-admin-list-td\">\n {session.title || `Chat ${session.id.slice(0, 8)}...`}\n </div>\n <div className=\"cedros-admin-list-td\">{session.messageCount}</div>\n </div>\n ))}\n </div>\n {totalPages > 1 && (\n <Pagination\n currentPage={currentPage}\n totalPages={totalPages}\n total={total}\n onPageChange={onPageChange}\n />\n )}\n </>\n );\n}\n\ninterface ReferralsTabProps {\n referrals: ReferredUserItem[];\n total: number;\n currentPage: number;\n totalPages: number;\n onPageChange: (page: number) => void;\n isLoading: boolean;\n error: string | null;\n onRetry: () => void;\n}\n\nfunction ReferralsTab({\n referrals,\n total,\n currentPage,\n totalPages,\n onPageChange,\n isLoading,\n error,\n onRetry,\n}: ReferralsTabProps) {\n if (error) {\n return (\n <div className=\"cedros-admin-tab-error\">\n <p className=\"cedros-admin-error-inline\">{error}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={onRetry}\n >\n Retry\n </button>\n </div>\n );\n }\n\n if (isLoading && referrals.length === 0) {\n return (\n <div className=\"cedros-admin-tab-loading\">\n <span className=\"cedros-admin-loading-indicator\" />\n <span>Loading referrals...</span>\n </div>\n );\n }\n\n if (total === 0) {\n return <div className=\"cedros-admin-empty-message\">No referred users found.</div>;\n }\n\n return (\n <>\n <div className=\"cedros-admin-list-table\">\n <div className=\"cedros-admin-list-thead\">\n <div className=\"cedros-admin-list-th\">Name</div>\n <div className=\"cedros-admin-list-th\">Email</div>\n <div className=\"cedros-admin-list-th\">Joined</div>\n <div className=\"cedros-admin-list-th\">Last Login</div>\n </div>\n {referrals.map((r) => (\n <div key={r.id} className=\"cedros-admin-list-row\">\n <div className=\"cedros-admin-list-td\">{r.name || '—'}</div>\n <div className=\"cedros-admin-list-td\">{r.email || '—'}</div>\n <div className=\"cedros-admin-list-td\">{formatDate(r.createdAt)}</div>\n <div className=\"cedros-admin-list-td\">\n {r.lastLoginAt ? formatDateTime(r.lastLoginAt) : '—'}\n </div>\n </div>\n ))}\n </div>\n {totalPages > 1 && (\n <Pagination\n currentPage={currentPage}\n totalPages={totalPages}\n total={total}\n onPageChange={onPageChange}\n />\n )}\n </>\n );\n}\n\n// =============================================================================\n// KYC Tab Component\n// =============================================================================\n\nconst KYC_OVERRIDE_OPTIONS = [\n { value: 'none', label: 'None (reset)' },\n { value: 'verified', label: 'Verified' },\n { value: 'failed', label: 'Failed' },\n];\n\ninterface KycTabProps {\n kycData: AdminUserKycResponse | null;\n /** KYC status from the AdminUser object (faster-loading summary) */\n userKycStatus?: string;\n userKycVerifiedAt?: string;\n userKycExpiresAt?: string;\n error: string | null;\n onRetry: () => void;\n onOverride: (status: string) => Promise<void>;\n}\n\nfunction KycTab({\n kycData,\n userKycStatus,\n userKycVerifiedAt,\n userKycExpiresAt,\n error,\n onRetry,\n onOverride,\n}: KycTabProps) {\n const [overrideStatus, setOverrideStatus] = useState('none');\n const [overrideInProgress, setOverrideInProgress] = useState(false);\n const [overrideError, setOverrideError] = useState<string | null>(null);\n\n const effectiveStatus = kycData?.status ?? userKycStatus ?? 'none';\n const effectiveVerifiedAt = kycData?.verifiedAt ?? userKycVerifiedAt;\n const effectiveExpiresAt = kycData?.expiresAt ?? userKycExpiresAt;\n\n const handleOverride = async () => {\n const confirmed = window.confirm(\n `Override KYC status to \"${overrideStatus}\" for this user?`\n );\n if (!confirmed) return;\n setOverrideInProgress(true);\n setOverrideError(null);\n try {\n await onOverride(overrideStatus);\n } catch (err) {\n setOverrideError(err instanceof Error ? err.message : 'Override failed');\n } finally {\n setOverrideInProgress(false);\n }\n };\n\n if (error) {\n return (\n <div className=\"cedros-admin-tab-error\">\n <p className=\"cedros-admin-error-inline\">{error}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={onRetry}\n >\n Retry\n </button>\n </div>\n );\n }\n\n if (!kycData && !userKycStatus) {\n return (\n <div className=\"cedros-admin-tab-loading\">\n <span className=\"cedros-admin-loading-indicator\" />\n <span>Loading KYC data...</span>\n </div>\n );\n }\n\n return (\n <div className=\"cedros-kyc-admin-tab\">\n {/* Status summary */}\n <div className=\"cedros-kyc-admin-tab-summary\">\n <div className=\"cedros-kyc-admin-tab-row\">\n <span className=\"cedros-kyc-admin-tab-label\">Status</span>\n <span\n className={`cedros-admin-status-badge cedros-kyc-status-${effectiveStatus}`}\n >\n {effectiveStatus}\n </span>\n </div>\n {effectiveVerifiedAt && (\n <div className=\"cedros-kyc-admin-tab-row\">\n <span className=\"cedros-kyc-admin-tab-label\">Verified at</span>\n <span>{formatDateTime(effectiveVerifiedAt)}</span>\n </div>\n )}\n {effectiveExpiresAt && (\n <div className=\"cedros-kyc-admin-tab-row\">\n <span className=\"cedros-kyc-admin-tab-label\">Expires at</span>\n <span>{formatDateTime(effectiveExpiresAt)}</span>\n </div>\n )}\n </div>\n\n {/* Override */}\n <div className=\"cedros-kyc-admin-override\">\n <span className=\"cedros-kyc-admin-override-label\">Override status</span>\n <select\n className=\"cedros-kyc-admin-override-select\"\n value={overrideStatus}\n onChange={(e) => setOverrideStatus(e.target.value)}\n disabled={overrideInProgress}\n aria-label=\"Select KYC override status\"\n >\n {KYC_OVERRIDE_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={handleOverride}\n disabled={overrideInProgress}\n >\n {overrideInProgress ? 'Saving...' : 'Apply Override'}\n </button>\n {overrideError && (\n <p className=\"cedros-admin-error-inline\">{overrideError}</p>\n )}\n </div>\n\n {/* Session history */}\n {kycData && kycData.sessions.length > 0 ? (\n <div className=\"cedros-admin-list-table\">\n <div className=\"cedros-admin-list-thead\">\n <div className=\"cedros-admin-list-th\">Date</div>\n <div className=\"cedros-admin-list-th\">Provider</div>\n <div className=\"cedros-admin-list-th\">Status</div>\n <div className=\"cedros-admin-list-th\">Error</div>\n <div className=\"cedros-admin-list-th\">Completed</div>\n </div>\n {kycData.sessions.map((session: AdminUserKycSession) => (\n <div key={session.id} className=\"cedros-admin-list-row\">\n <div className=\"cedros-admin-list-td\">{formatDateTime(session.createdAt)}</div>\n <div className=\"cedros-admin-list-td\">{session.provider}</div>\n <div className=\"cedros-admin-list-td\">\n <span\n className={`cedros-admin-status-badge cedros-kyc-status-${session.status}`}\n >\n {session.status}\n </span>\n </div>\n <div className=\"cedros-admin-list-td cedros-admin-list-td-muted\">\n {session.errorCode\n ? `${session.errorCode}${session.errorReason ? `: ${session.errorReason}` : ''}`\n : '—'}\n </div>\n <div className=\"cedros-admin-list-td\">\n {session.completedAt ? formatDateTime(session.completedAt) : '—'}\n </div>\n </div>\n ))}\n </div>\n ) : (\n kycData && (\n <div className=\"cedros-admin-empty-message\">No verification sessions found.</div>\n )\n )}\n </div>\n );\n}\n\n// =============================================================================\n// Accreditation Tab Component\n// =============================================================================\n\nconst ACCREDITATION_OVERRIDE_OPTIONS = [\n { value: 'none', label: 'None (reset)' },\n { value: 'approved', label: 'Approved' },\n { value: 'rejected', label: 'Rejected' },\n];\n\ninterface AccreditationTabProps {\n accreditationData: AdminUserAccreditationResponse | null;\n userAccreditationStatus?: string;\n userAccreditationVerifiedAt?: string;\n userAccreditationExpiresAt?: string;\n error: string | null;\n onRetry: () => void;\n onOverride: (status: string) => Promise<void>;\n onReview: (\n submissionId: string,\n approved: boolean,\n reviewerNotes?: string,\n rejectionReason?: string\n ) => Promise<void>;\n}\n\nfunction AccreditationTab({\n accreditationData,\n userAccreditationStatus,\n userAccreditationVerifiedAt,\n userAccreditationExpiresAt,\n error,\n onRetry,\n onOverride,\n onReview,\n}: AccreditationTabProps) {\n const [overrideStatus, setOverrideStatus] = useState('none');\n const [overrideInProgress, setOverrideInProgress] = useState(false);\n const [overrideError, setOverrideError] = useState<string | null>(null);\n const [reviewingId, setReviewingId] = useState<string | null>(null);\n const [reviewNotes, setReviewNotes] = useState('');\n const [reviewRejection, setReviewRejection] = useState('');\n const [reviewInProgress, setReviewInProgress] = useState(false);\n const [reviewError, setReviewError] = useState<string | null>(null);\n\n const effectiveStatus =\n accreditationData?.status ?? userAccreditationStatus ?? 'none';\n const effectiveVerifiedAt =\n accreditationData?.verifiedAt ?? userAccreditationVerifiedAt;\n const effectiveExpiresAt =\n accreditationData?.expiresAt ?? userAccreditationExpiresAt;\n\n const handleOverride = async () => {\n const confirmed = window.confirm(\n `Override accreditation status to \"${overrideStatus}\" for this user?`\n );\n if (!confirmed) return;\n setOverrideInProgress(true);\n setOverrideError(null);\n try {\n await onOverride(overrideStatus);\n } catch (err) {\n setOverrideError(err instanceof Error ? err.message : 'Override failed');\n } finally {\n setOverrideInProgress(false);\n }\n };\n\n const handleReview = async (submissionId: string, approved: boolean) => {\n const label = approved ? 'approve' : 'reject';\n const confirmed = window.confirm(`${label.charAt(0).toUpperCase() + label.slice(1)} this submission?`);\n if (!confirmed) return;\n setReviewInProgress(true);\n setReviewError(null);\n try {\n await onReview(\n submissionId,\n approved,\n reviewNotes || undefined,\n !approved ? reviewRejection || undefined : undefined\n );\n setReviewingId(null);\n setReviewNotes('');\n setReviewRejection('');\n } catch (err) {\n setReviewError(err instanceof Error ? err.message : 'Review failed');\n } finally {\n setReviewInProgress(false);\n }\n };\n\n if (error) {\n return (\n <div className=\"cedros-admin-tab-error\">\n <p className=\"cedros-admin-error-inline\">{error}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={onRetry}\n >\n Retry\n </button>\n </div>\n );\n }\n\n if (!accreditationData && !userAccreditationStatus) {\n return (\n <div className=\"cedros-admin-tab-loading\">\n <span className=\"cedros-admin-loading-indicator\" />\n <span>Loading accreditation data...</span>\n </div>\n );\n }\n\n return (\n <div className=\"cedros-accreditation-admin-tab\">\n {/* Status summary */}\n <div className=\"cedros-kyc-admin-tab-summary\">\n <div className=\"cedros-kyc-admin-tab-row\">\n <span className=\"cedros-kyc-admin-tab-label\">Status</span>\n <span\n className={`cedros-admin-status-badge cedros-accreditation-status-${effectiveStatus}`}\n >\n {effectiveStatus}\n </span>\n </div>\n {effectiveVerifiedAt && (\n <div className=\"cedros-kyc-admin-tab-row\">\n <span className=\"cedros-kyc-admin-tab-label\">Verified at</span>\n <span>{formatDateTime(effectiveVerifiedAt)}</span>\n </div>\n )}\n {effectiveExpiresAt && (\n <div className=\"cedros-kyc-admin-tab-row\">\n <span className=\"cedros-kyc-admin-tab-label\">Expires at</span>\n <span>{formatDateTime(effectiveExpiresAt)}</span>\n </div>\n )}\n </div>\n\n {/* Override */}\n <div className=\"cedros-kyc-admin-override\">\n <span className=\"cedros-kyc-admin-override-label\">Override status</span>\n <select\n className=\"cedros-kyc-admin-override-select\"\n value={overrideStatus}\n onChange={(e) => setOverrideStatus(e.target.value)}\n disabled={overrideInProgress}\n aria-label=\"Select accreditation override status\"\n >\n {ACCREDITATION_OVERRIDE_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={handleOverride}\n disabled={overrideInProgress}\n >\n {overrideInProgress ? 'Saving...' : 'Apply Override'}\n </button>\n {overrideError && <p className=\"cedros-admin-error-inline\">{overrideError}</p>}\n </div>\n\n {/* Submission history */}\n {accreditationData && accreditationData.submissions.length > 0 ? (\n <>\n <div className=\"cedros-admin-list-table\">\n <div className=\"cedros-admin-list-thead\">\n <div className=\"cedros-admin-list-th\">Date</div>\n <div className=\"cedros-admin-list-th\">Method</div>\n <div className=\"cedros-admin-list-th\">Status</div>\n <div className=\"cedros-admin-list-th\">Expires</div>\n <div className=\"cedros-admin-list-th\">Actions</div>\n </div>\n {accreditationData.submissions.map((sub: AccreditationSubmissionItem) => (\n <div key={sub.id} className=\"cedros-admin-list-row\">\n <div className=\"cedros-admin-list-td\">{formatDateTime(sub.createdAt)}</div>\n <div className=\"cedros-admin-list-td\">{sub.method.replace(/_/g, ' ')}</div>\n <div className=\"cedros-admin-list-td\">\n <span\n className={`cedros-admin-status-badge cedros-accreditation-status-${sub.status}`}\n >\n {sub.status}\n </span>\n </div>\n <div className=\"cedros-admin-list-td\">\n {sub.expiresAt ? formatDateTime(sub.expiresAt) : '—'}\n </div>\n <div className=\"cedros-admin-list-td cedros-admin-list-td-actions\">\n {sub.status === 'pending' && (\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={() =>\n setReviewingId(reviewingId === sub.id ? null : sub.id)\n }\n >\n Review\n </button>\n )}\n </div>\n </div>\n ))}\n </div>\n {reviewingId && (\n <div className=\"cedros-accreditation-review-panel\">\n <p className=\"cedros-accreditation-review-title\">Review submission</p>\n <label className=\"cedros-kyc-admin-tab-label\" htmlFor=\"review-notes\">\n Reviewer notes (internal)\n </label>\n <input\n id=\"review-notes\"\n type=\"text\"\n className=\"cedros-input cedros-input-sm\"\n value={reviewNotes}\n onChange={(e) => setReviewNotes(e.target.value)}\n placeholder=\"Optional internal notes\"\n disabled={reviewInProgress}\n />\n <label\n className=\"cedros-kyc-admin-tab-label\"\n htmlFor=\"review-rejection\"\n >\n Rejection reason (shown to user if rejected)\n </label>\n <input\n id=\"review-rejection\"\n type=\"text\"\n className=\"cedros-input cedros-input-sm\"\n value={reviewRejection}\n onChange={(e) => setReviewRejection(e.target.value)}\n placeholder=\"Required when rejecting\"\n disabled={reviewInProgress}\n />\n <div className=\"cedros-accreditation-review-actions\">\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={() => handleReview(reviewingId, true)}\n disabled={reviewInProgress}\n >\n {reviewInProgress ? 'Saving...' : 'Approve'}\n </button>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm cedros-admin-btn-danger\"\n onClick={() => handleReview(reviewingId, false)}\n disabled={reviewInProgress || !reviewRejection.trim()}\n >\n {reviewInProgress ? 'Saving...' : 'Reject'}\n </button>\n </div>\n {reviewError && <p className=\"cedros-admin-error-inline\">{reviewError}</p>}\n </div>\n )}\n </>\n ) : (\n accreditationData && (\n <div className=\"cedros-admin-empty-message\">No accreditation submissions found.</div>\n )\n )}\n </div>\n );\n}\n\ninterface PaginationProps {\n currentPage: number;\n totalPages: number;\n total: number;\n onPageChange: (page: number) => void;\n}\n\nfunction Pagination({ currentPage, totalPages, total, onPageChange }: PaginationProps) {\n return (\n <div className=\"cedros-admin-pagination\">\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={() => onPageChange(currentPage - 1)}\n disabled={currentPage <= 1}\n >\n Previous\n </button>\n <span className=\"cedros-admin-page-info\">\n Page {currentPage} of {totalPages} ({total} total)\n </span>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline cedros-button-sm\"\n onClick={() => onPageChange(currentPage + 1)}\n disabled={currentPage >= totalPages}\n >\n Next\n </button>\n </div>\n );\n}\n","import { useCallback, useEffect, useMemo, useState } from 'react';\nimport type { AdminUserStatsResponse } from '../../../types';\nimport { useAdminUsers } from '../../../hooks/useAdminUsers';\nimport { useSystemSettings } from '../../../hooks/useSystemSettings';\nimport type { StatItem } from '../StatsBar';\n\nconst METHOD_ORDER = ['email', 'google', 'apple', 'solana', 'webauthn', 'sso'] as const;\n\nconst METHOD_LABELS: Record<(typeof METHOD_ORDER)[number], string> = {\n email: 'Email Users',\n google: 'Google Users',\n apple: 'Apple Users',\n solana: 'Solana Users',\n webauthn: 'Passkey Users',\n sso: 'SSO Provider Users',\n};\n\nconst METHOD_SETTINGS: Record<(typeof METHOD_ORDER)[number], string> = {\n email: 'auth_email_enabled',\n google: 'auth_google_enabled',\n apple: 'auth_apple_enabled',\n solana: 'auth_solana_enabled',\n webauthn: 'auth_webauthn_enabled',\n sso: 'feature_sso',\n};\n\nexport interface UsersStatsSummary {\n statsItems: StatItem[];\n isLoading: boolean;\n error: string | null;\n refresh: () => Promise<void>;\n}\n\nexport function useUsersStatsSummary(): UsersStatsSummary {\n const { getStats } = useAdminUsers();\n const { fetchSettings, getValue } = useSystemSettings();\n const [stats, setStats] = useState<AdminUserStatsResponse | null>(null);\n const [isLoading, setIsLoading] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const [settingsFetched, setSettingsFetched] = useState(false);\n\n useEffect(() => {\n if (!settingsFetched) {\n fetchSettings();\n setSettingsFetched(true);\n }\n }, [fetchSettings, settingsFetched]);\n\n const isSettingEnabled = useCallback(\n (key: string): boolean => {\n const value = getValue(key);\n if (value === undefined) return false;\n return value === 'true' || value === '1';\n },\n [getValue]\n );\n\n const refresh = useCallback(async () => {\n setIsLoading(true);\n setError(null);\n\n try {\n const result = await getStats();\n setStats(result);\n } catch (err) {\n setError(err instanceof Error ? err.message : 'Failed to load user stats');\n } finally {\n setIsLoading(false);\n }\n }, [getStats]);\n\n useEffect(() => {\n void refresh();\n }, [refresh]);\n\n const statsItems = useMemo(() => {\n const items: StatItem[] = [{ label: 'Total Users', value: stats?.total ?? '—' }];\n\n METHOD_ORDER.forEach((method) => {\n if (!isSettingEnabled(METHOD_SETTINGS[method])) return;\n items.push({\n label: METHOD_LABELS[method],\n value: stats?.authMethodCounts[method] ?? 0,\n });\n });\n\n return items;\n }, [stats, isSettingEnabled]);\n\n return { statsItems, isLoading, error, refresh };\n}\n"],"names":["AdminUserApiClient","baseUrl","timeoutMs","retryAttempts","getAccessToken","ApiClient","params","query","queryString","url","error","handleApiError","userId","isAdmin","data","status","submissionId","approved","reviewerNotes","rejectionReason","expiryDays","useAdminUsers","config","_internal","useCedrosLogin","users","setUsers","useState","total","setTotal","isLoading","setIsLoading","setError","lastParams","setLastParams","apiClient","useMemo","listUsers","useCallback","response","err","getUser","setSystemAdmin","prev","user","updateUser","updated","deleteUser","forcePasswordReset","adjustCredits","amount","reason","getUserDeposits","getUserCredits","getUserWithdrawalHistory","getUserChats","getUserReferrals","getStats","refresh","clearError","formatDate","dateString","truncateId","id","formatBalance","lamports","AdminUserList","pageSize","refreshInterval","currentUserId","className","onLoad","onUserClick","offset","setOffset","loadError","setLoadError","sortField","setSortField","sortOrder","setSortOrder","toggleSort","field","sortedUsers","a","b","aVal","bVal","fetchUsers","result","useEffect","interval","totalPages","currentPage","goToPage","page","newOffset","jsxs","jsx","Fragment","isCurrentUser","e","formatDateTime","formatSol","formatCredits","formatTxType","txType","formatTxDescription","referenceType","AdminUserDetail","onBack","onEditUser","onAdjustCredits","cedrosPayEnabled","kycApiClient","setUser","credits","setCredits","deposits","setDeposits","chats","setChats","referrals","setReferrals","kycData","setKycData","accreditationData","setAccreditationData","activeTab","setActiveTab","userError","setUserError","creditsError","setCreditsError","depositsError","setDepositsError","chatsError","setChatsError","referralsError","setReferralsError","kycError","setKycError","accreditationError","setAccreditationError","actionInProgress","setActionInProgress","depositsOffset","setDepositsOffset","transactionsOffset","setTransactionsOffset","chatsOffset","setChatsOffset","referralsOffset","setReferralsOffset","fetchUser","userData","fetchDeposits","depositsData","fetchCredits","creditsData","fetchChats","chatsData","fetchReferrals","fetchKyc","fetchAccreditation","handleAccreditationOverride","handleAccreditationReview","handleKycOverride","handleDelete","handlePasswordReset","depositsTotalPages","depositsCurrentPage","transactionsTotalPages","transactionsCurrentPage","goToDepositsPage","goToTransactionsPage","chatsTotalPages","chatsCurrentPage","goToChatsPage","referralsTotalPages","referralsCurrentPage","goToReferralsPage","method","DepositsTab","TransactionsTab","ChatsTab","ReferralsTab","KycTab","AccreditationTab","onPageChange","onRetry","deposit","Pagination","transactions","tx","sessions","session","r","KYC_OVERRIDE_OPTIONS","userKycStatus","userKycVerifiedAt","userKycExpiresAt","onOverride","overrideStatus","setOverrideStatus","overrideInProgress","setOverrideInProgress","overrideError","setOverrideError","effectiveStatus","effectiveVerifiedAt","effectiveExpiresAt","handleOverride","opt","ACCREDITATION_OVERRIDE_OPTIONS","userAccreditationStatus","userAccreditationVerifiedAt","userAccreditationExpiresAt","onReview","reviewingId","setReviewingId","reviewNotes","setReviewNotes","reviewRejection","setReviewRejection","reviewInProgress","setReviewInProgress","reviewError","setReviewError","handleReview","label","sub","METHOD_ORDER","METHOD_LABELS","METHOD_SETTINGS","useUsersStatsSummary","fetchSettings","getValue","useSystemSettings","stats","setStats","settingsFetched","setSettingsFetched","isSettingEnabled","key","value","items"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cedros/login-react",
3
- "version": "0.0.41",
3
+ "version": "0.0.43",
4
4
  "description": "React component library for authentication with email/password, Google OAuth, and Solana wallet sign-in",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -1 +0,0 @@
1
- "use strict";const e=require("react/jsx-runtime"),u=require("react"),A=require("./useCedrosLogin-DtJorrE7.cjs"),L=require("./useSystemSettings-B2jY51ob.cjs");function D(t){const s=Math.floor(t/86400),a=Math.floor(t%86400/3600),n=Math.floor(t%3600/60),l=t%60;return{days:s,hours:a,minutes:n,seconds:l}}function R(t){const{days:s,hours:a,minutes:n}=D(t),l=[];return s>0&&l.push(`${s}d`),a>0&&l.push(`${a}h`),n>0&&l.push(`${n}m`),l.length===0&&l.push(`${t}s`),l.join(" ")}const C={auth_email_enabled:{key:"auth_email_enabled",label:"Enable Email Authentication",description:"Allow users to sign up and log in with email/password.",inputType:"boolean"},auth_email_require_verification:{key:"auth_email_require_verification",label:"Require Email Verification",description:"Users must verify their email address before they can log in.",inputType:"boolean"},auth_email_block_disposable:{key:"auth_email_block_disposable",label:"Block Disposable Emails",description:"Reject registrations from known disposable email providers.",inputType:"boolean"},auth_google_enabled:{key:"auth_google_enabled",label:"Enable Google Sign-In",description:'Allow users to authenticate with their Google account. Configure at <a href="https://console.cloud.google.com/apis/credentials" target="_blank" rel="noopener">Google Cloud Console &gt; Credentials</a>.',inputType:"boolean"},auth_google_client_id:{key:"auth_google_client_id",label:"Google Client ID",description:"OAuth 2.0 client ID from Google Cloud Console. Create a Web application credential and add your frontend URL to Authorized JavaScript origins.",inputType:"text"},auth_apple_enabled:{key:"auth_apple_enabled",label:"Enable Sign in with Apple",description:'Allow users to authenticate with their Apple ID. Configure at <a href="https://developer.apple.com/account/resources/identifiers" target="_blank" rel="noopener">Apple Developer &gt; Identifiers</a>.',inputType:"boolean"},auth_apple_client_id:{key:"auth_apple_client_id",label:"Apple Services ID",description:"Your Client ID (e.g. com.yourdomain.service). Create at Identifiers &gt; Services IDs, then enable Sign in with Apple and add your frontend URL as a Return URL (e.g. https://yourdomain.com).",inputType:"text",placeholder:"com.yourdomain.service"},auth_apple_team_id:{key:"auth_apple_team_id",label:"Apple Team ID",description:'Identifies your developer account. Found at the top-right of <a href="https://developer.apple.com/account" target="_blank" rel="noopener">Apple Developer</a>.',inputType:"text"},auth_solana_enabled:{key:"auth_solana_enabled",label:"Enable Solana Wallet Auth",description:"Allow users to authenticate by signing with their Solana wallet.",inputType:"boolean"},auth_solana_challenge_expiry:{key:"auth_solana_challenge_expiry",label:"Challenge Expiry",description:"How long a wallet signature challenge is valid.",inputType:"duration",min:60,presets:[{label:"1 minute",value:"60"},{label:"5 minutes",value:"300"},{label:"10 minutes",value:"600"}]},auth_webauthn_enabled:{key:"auth_webauthn_enabled",label:"Enable WebAuthn/Passkeys",description:"Allow passwordless authentication with FIDO2/WebAuthn credentials.",inputType:"boolean"},auth_webauthn_rp_id:{key:"auth_webauthn_rp_id",label:"Relying Party ID",description:"Usually your domain (e.g., example.com). Passkeys are bound to this.",inputType:"text"},auth_webauthn_rp_name:{key:"auth_webauthn_rp_name",label:"Relying Party Name",description:"Display name shown to users during passkey registration.",inputType:"text"},auth_webauthn_rp_origin:{key:"auth_webauthn_rp_origin",label:"Allowed Origins",description:"Comma-separated origins allowed for WebAuthn (e.g., https://example.com).",inputType:"text"},auth_instantlink_enabled:{key:"auth_instantlink_enabled",label:"Enable Instant Link",description:'When enabled, "Forgot your password?" on the sign-in form sends a one-time sign-in link instead of a password reset. This replaces the password reset flow — it is not a separate login button.',inputType:"boolean"},auth_instantlink_expiry:{key:"auth_instantlink_expiry",label:"Link Expiry",description:"How long the magic link remains valid.",inputType:"duration",min:60,presets:[{label:"5 minutes",value:"300"},{label:"15 minutes",value:"900"},{label:"30 minutes",value:"1800"},{label:"1 hour",value:"3600"}]},auth_instantlink_rate_limit:{key:"auth_instantlink_rate_limit",label:"Rate Limit",description:"Maximum instant link requests per email per hour.",inputType:"select",presets:[{label:"3 per hour",value:"3"},{label:"5 per hour",value:"5"},{label:"10 per hour",value:"10"}]},feature_organizations:{key:"feature_organizations",label:"Organizations",description:"Enable multi-user organizations with role-based access.",inputType:"boolean"},feature_sso:{key:"feature_sso",label:"Enterprise SSO",description:"Enable SAML/OIDC single sign-on for enterprise customers.",inputType:"boolean"},feature_mfa:{key:"feature_mfa",label:"Two-Factor Authentication",description:"Allow users to enable TOTP-based two-factor authentication for email/password sign-in. OAuth (Google, Apple) and passkey logins are not affected — those providers handle their own verification.",inputType:"boolean"},feature_wallet_signing:{key:"feature_wallet_signing",label:"Enable Embedded Wallet",description:"Enable the embedded wallet for transaction signing.",inputType:"boolean"},wallet_recovery_mode:{key:"wallet_recovery_mode",label:"Recovery Mode",description:"Controls whether users can recover their embedded wallet seed. <b>Share C Only</b> lets users export a single key share (cannot reconstruct the full seed). <b>Full Seed</b> lets users export the complete seed phrase. <b>No Recovery</b> prevents any seed export — required when Private Deposits are enabled, because recoverable seeds would let users front-run privacy withdrawals.",inputType:"select",presets:[{label:"Share C Only (Recommended)",value:"share_c_only"},{label:"Full Seed Phrase",value:"full_seed"},{label:"No Recovery (Required for Private Deposits)",value:"none"}]},feature_credits:{key:"feature_credits",label:"Credit System",description:"Enable the deposits and credits system. Users can deposit tokens to receive platform credits.",inputType:"boolean"},feature_user_withdrawals:{key:"feature_user_withdrawals",label:"User Withdrawals",description:"Allow users to initiate withdrawals from their embedded wallet to external addresses. This is separate from the automated privacy withdrawal worker, which moves funds from the privacy pool to the treasury.",inputType:"boolean"},security_require_mfa:{key:"security_require_mfa",label:"Require Two-Factor Authentication",description:'Require users with email/password credentials to set up TOTP two-factor authentication. Users will be prompted to enroll after their next sign-in. Does not affect OAuth, passkey, or wallet sign-in methods. Works independently of the "Two-Factor Authentication" feature flag (which controls UI visibility).',inputType:"boolean"},security_cors_origins:{key:"security_cors_origins",label:"CORS Origins",description:"Allowed origins for cross-origin requests (comma-separated). Empty = same origin only.",inputType:"text"},security_cookie_domain:{key:"security_cookie_domain",label:"Cookie Domain",description:"Domain for auth cookies. Empty uses the request origin.",inputType:"text"},security_cookie_secure:{key:"security_cookie_secure",label:"Secure Cookies",description:"Require HTTPS for cookies. Disable only for local development.",inputType:"boolean"},security_cookie_same_site:{key:"security_cookie_same_site",label:"Cookie SameSite",description:'SameSite policy for cookies. Use "none" only if needed for cross-site embeds.',inputType:"select",presets:[{label:"Strict",value:"strict"},{label:"Lax (Recommended)",value:"lax"},{label:"None (cross-site)",value:"none"}]},security_session_timeout:{key:"security_session_timeout",label:"Session Timeout",description:"How long sessions remain valid before requiring re-authentication.",inputType:"duration",min:300,presets:[{label:"1 hour",value:"3600"},{label:"24 hours",value:"86400"},{label:"7 days",value:"604800"},{label:"30 days",value:"2592000"}]},security_jwt_issuer:{key:"security_jwt_issuer",label:"JWT Issuer",description:"Issuer claim for JWTs. Empty uses the server URL.",inputType:"text"},security_jwt_audience:{key:"security_jwt_audience",label:"JWT Audience",description:"Audience claim for JWTs. Empty uses default.",inputType:"text"},email_provider:{key:"email_provider",label:"Email Provider",description:"Select a provider to auto-configure SMTP host, port, and TLS. Choose Custom SMTP to enter settings manually.",inputType:"select",presets:[{label:"Mailgun",value:"mailgun"},{label:"SendGrid",value:"sendgrid"},{label:"Postmark",value:"postmark"},{label:"AWS SES",value:"ses"},{label:"Resend",value:"resend"},{label:"Custom SMTP",value:"custom"}]},email_smtp_host:{key:"email_smtp_host",label:"SMTP Host",description:"SMTP server hostname. Auto-filled when selecting a provider above.",inputType:"text",placeholder:"smtp.example.com"},email_smtp_port:{key:"email_smtp_port",label:"SMTP Port",description:"SMTP server port. Most providers use 587 (TLS).",inputType:"select",presets:[{label:"587 (TLS)",value:"587"},{label:"465 (SSL)",value:"465"},{label:"25 (Plain)",value:"25"}]},email_smtp_user:{key:"email_smtp_user",label:"SMTP Username",description:'Username for SMTP authentication. For SendGrid use "apikey", for Postmark use your server API token, for Mailgun use your full Mailgun SMTP login.',inputType:"text"},email_smtp_password:{key:"email_smtp_password",label:"API Key",description:"API key or password for your email provider. For SendGrid this is your API key, for Postmark your server API token, for Mailgun your SMTP password.",inputType:"secret"},email_smtp_tls:{key:"email_smtp_tls",label:"Use TLS",description:"Enable TLS encryption for SMTP connections. Required by most providers.",inputType:"boolean"},email_from_address:{key:"email_from_address",label:"From Address",description:"Sender email address for verification, password reset, and instant link emails. Must be verified with your provider.",inputType:"text",placeholder:"noreply@yourdomain.com"},email_from_name:{key:"email_from_name",label:"From Name",description:'Display name shown in the "From" field of outbound emails.',inputType:"text",placeholder:"My App"},email_subject_verification:{key:"email_subject_verification",label:"Verification Email Subject",description:'Custom subject for email verification messages. Leave empty for the default: "Verify your email address".',inputType:"text",placeholder:"Verify your email address"},email_subject_password_reset:{key:"email_subject_password_reset",label:"Password Reset Subject",description:'Custom subject for password reset emails. Leave empty for the default: "Reset your password".',inputType:"text",placeholder:"Reset your password"},email_subject_instant_link:{key:"email_subject_instant_link",label:"Instant Link Subject",description:'Custom subject for instant link sign-in emails. Leave empty for the default: "Your sign-in link".',inputType:"text",placeholder:"Your sign-in link"},email_subject_invite:{key:"email_subject_invite",label:"Invite Email Subject",description:"Custom subject for organization invite emails. Leave empty for the default which includes the org name.",inputType:"text",placeholder:"You've been invited to join..."},email_subject_security_alert:{key:"email_subject_security_alert",label:"Security Alert Subject",description:'Custom subject for new device sign-in alerts. Leave empty for the default: "New sign-in to your account".',inputType:"text",placeholder:"New sign-in to your account"},webhook_enabled:{key:"webhook_enabled",label:"Enable Webhooks",description:"Send notifications to a Discord or Slack webhook URL.",inputType:"boolean"},webhook_url:{key:"webhook_url",label:"Webhook URL",description:"Discord or Slack webhook URL to receive notifications.",inputType:"text",placeholder:"https://discord.com/api/webhooks/..."},webhook_notify_registrations:{key:"webhook_notify_registrations",label:"New Registrations",description:"Notify when a new user registers.",inputType:"boolean"},webhook_notify_signins:{key:"webhook_notify_signins",label:"Sign-Ins",description:"Notify when a user signs in.",inputType:"boolean"},webhook_notify_deposits:{key:"webhook_notify_deposits",label:"Deposits",description:"Notify when a user makes a deposit.",inputType:"boolean"},server_frontend_url:{key:"server_frontend_url",label:"Frontend URL",description:"URL of your frontend app (for redirects and email links).",inputType:"text"},server_base_path:{key:"server_base_path",label:"Base Path",description:"Base path for auth endpoints (e.g., /auth).",inputType:"text"},server_trust_proxy:{key:"server_trust_proxy",label:"Trust Proxy",description:"Trust X-Forwarded-For headers. Enable if behind a reverse proxy.",inputType:"boolean"},feature_cedros_pay:{key:"feature_cedros_pay",label:"Cedros Pay Integration",description:"Enable Cedros Pay integration. When enabled, shows the Integrations tab with API key configuration. Not needed for co-located deployments using JWT/JWKS inter-service auth.",inputType:"boolean"},server_cedros_pay_api_key:{key:"server_cedros_pay_api_key",label:"Cedros Pay API Key",description:"API key for Cedros Pay to authenticate with this server. Copy this into your Cedros Pay settings.",inputType:"secret"},jupiter_api_key:{key:"jupiter_api_key",label:"Jupiter API Key",description:'API key for Jupiter Ultra API (gasless swaps). Get a free key at <a href="https://portal.jup.ag" target="_blank" rel="noopener">portal.jup.ag</a>.',inputType:"secret"},server_metrics_api_key:{key:"server_metrics_api_key",label:"Metrics API Key",description:"API key for Prometheus/Grafana to scrape the /metrics endpoint. Use with Authorization: Bearer header.",inputType:"secret"},server_log_level:{key:"server_log_level",label:"Log Level",description:"Minimum severity level for log output. Lower levels are more verbose.",inputType:"select",presets:[{label:"Trace (most verbose)",value:"trace"},{label:"Debug",value:"debug"},{label:"Info",value:"info"},{label:"Warn",value:"warn"},{label:"Error (least verbose)",value:"error"}]},server_log_format:{key:"server_log_format",label:"Log Format",description:"Output format for log messages.",inputType:"select",presets:[{label:"JSON (structured)",value:"json"},{label:"Pretty (human-readable)",value:"pretty"}]},server_environment:{key:"server_environment",label:"Environment",description:"Deployment environment. Affects default behaviors and log verbosity.",inputType:"select",presets:[{label:"Development",value:"development"},{label:"Staging",value:"staging"},{label:"Production",value:"production"}]},privacy_period_secs:{key:"privacy_period_secs",label:"Privacy Period",description:"How long deposits are held before withdrawal to provide timing privacy. Longer periods provide better privacy but delay user access to funds.",inputType:"duration",min:0,presets:[{label:"Disabled",value:"0"},{label:"1 hour",value:"3600"},{label:"6 hours",value:"21600"},{label:"24 hours",value:"86400"},{label:"7 days",value:"604800"},{label:"14 days",value:"1209600"},{label:"30 days",value:"2592000"}],warningThreshold:{below:3600,message:"Very short privacy periods may not provide adequate timing protection."}},treasury_wallet_address:{key:"treasury_wallet_address",label:"Treasury Wallet Address",description:"Solana wallet address where funds are sent. Used for privacy cash withdrawals, micro payment batches, and direct payments.",inputType:"text",placeholder:"e.g., 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU"},withdrawal_poll_interval_secs:{key:"withdrawal_poll_interval_secs",label:"Worker Poll Interval",description:"How often the withdrawal worker checks for deposits ready to process. Lower values process faster but increase server load.",inputType:"duration",min:60,presets:[{label:"1 minute",value:"60"},{label:"5 minutes",value:"300"},{label:"15 minutes",value:"900"},{label:"1 hour",value:"3600"},{label:"6 hours",value:"21600"}],warningThreshold:{below:60,message:"Polling more than once per minute may cause excessive load."}},withdrawal_batch_size:{key:"withdrawal_batch_size",label:"Batch Size",description:"Maximum number of withdrawals to process in a single batch. Higher values improve throughput but may cause timeouts.",inputType:"select",min:1,max:100,presets:[{label:"1 (Sequential)",value:"1"},{label:"5",value:"5"},{label:"10 (Recommended)",value:"10"},{label:"25",value:"25"},{label:"50",value:"50"},{label:"100 (Max)",value:"100"}]},withdrawal_timeout_secs:{key:"withdrawal_timeout_secs",label:"Transaction Timeout",description:"How long to wait for a withdrawal transaction to confirm before considering it failed.",inputType:"duration",min:30,presets:[{label:"30 seconds",value:"30"},{label:"1 minute",value:"60"},{label:"2 minutes",value:"120"},{label:"5 minutes",value:"300"}],warningThreshold:{below:30,message:"Very short timeouts may cause premature failure on slow networks."}},withdrawal_max_retries:{key:"withdrawal_max_retries",label:"Max Retries",description:"Number of times to retry a failed withdrawal before marking it as permanently failed.",inputType:"select",min:0,max:10,presets:[{label:"0 (No retries)",value:"0"},{label:"1",value:"1"},{label:"3 (Recommended)",value:"3"},{label:"5",value:"5"},{label:"10",value:"10"}]},withdrawal_percentage:{key:"withdrawal_percentage",label:"Withdrawal Percentage",description:"Percentage of ready funds to withdraw each cycle. Lower values spread withdrawals over time for better privacy.",inputType:"percentage",min:1,max:100,step:5,presets:[{label:"25%",value:"25"},{label:"50%",value:"50"},{label:"75%",value:"75"},{label:"100% (All at once)",value:"100"}],warningThreshold:{above:75,message:"High percentages may reduce timing privacy by processing most withdrawals together."}},partial_withdrawal_count:{key:"partial_withdrawal_count",label:"Partial Withdrawals",description:"Maximum partial withdrawals per batch. Partial withdrawals add noise to timing analysis. Set to 0 to disable.",inputType:"select",min:0,presets:[{label:"Disabled",value:"0"},{label:"1",value:"1"},{label:"3",value:"3"},{label:"5",value:"5"},{label:"10",value:"10"}]},partial_withdrawal_min_lamports:{key:"partial_withdrawal_min_lamports",label:"Min Balance for Partial",description:"Minimum account balance (in lamports) required before partial withdrawals are considered. 1 SOL = 1,000,000,000 lamports.",inputType:"select",min:0,presets:[{label:"0.1 SOL",value:"100000000"},{label:"0.5 SOL",value:"500000000"},{label:"1 SOL",value:"1000000000"},{label:"5 SOL",value:"5000000000"},{label:"10 SOL",value:"10000000000"}]},rate_limit_auth:{key:"rate_limit_auth",label:"Auth Request Limit",description:"Maximum authentication attempts (login, register, password reset) per IP per window. Protects against brute force attacks.",inputType:"select",min:1,unit:"requests",presets:[{label:"5 (Strict)",value:"5"},{label:"10 (Recommended)",value:"10"},{label:"20",value:"20"},{label:"50 (Permissive)",value:"50"}],warningThreshold:{above:20,message:"High auth limits may allow brute force attempts."}},rate_limit_general:{key:"rate_limit_general",label:"General Request Limit",description:"Maximum general API requests per IP per window. Affects all non-auth endpoints.",inputType:"select",min:1,unit:"requests",presets:[{label:"30",value:"30"},{label:"60 (Recommended)",value:"60"},{label:"120",value:"120"},{label:"300",value:"300"}]},rate_limit_credit:{key:"rate_limit_credit",label:"Credit Request Limit",description:"Maximum credit/balance check requests per IP per window. Higher for apps that poll balance frequently.",inputType:"select",min:1,unit:"requests",presets:[{label:"10",value:"10"},{label:"30 (Recommended)",value:"30"},{label:"60",value:"60"},{label:"120",value:"120"}]},rate_limit_window:{key:"rate_limit_window",label:"Rate Limit Window",description:'Time window for rate limiting. All limits above are "per window". Shorter windows are stricter.',inputType:"duration",min:1,presets:[{label:"30 seconds",value:"30"},{label:"1 minute",value:"60"},{label:"5 minutes",value:"300"},{label:"15 minutes",value:"900"}]},solana_rpc_url:{key:"solana_rpc_url",label:"Solana RPC URL",description:'Get a fast RPC endpoint from <a href="https://helius.dev" target="_blank" rel="noopener">Helius</a> or <a href="https://quicknode.com" target="_blank" rel="noopener">QuickNode</a>.',inputType:"text",placeholder:"https://api.mainnet-beta.solana.com"},solana_network:{key:"solana_network",label:"Solana Network",description:"The Solana network to use for deposits and withdrawals.",inputType:"select",presets:[{label:"Mainnet",value:"mainnet-beta"},{label:"Devnet",value:"devnet"}]},deposit_privacy_enabled:{key:"deposit_privacy_enabled",label:"Enable Private Deposits",description:"When enabled, deposits are held for a privacy period before withdrawal. Provides timing privacy but delays fund availability.",inputType:"boolean"},deposit_company_token:{key:"deposit_company_token",label:"Platform Token",description:"The token that represents platform credits. Deposits are converted to this token. Common choices: USDC, SOL.",inputType:"select",presets:[{label:"USDC",value:"USDC"},{label:"USDT",value:"USDT"},{label:"SOL",value:"SOL"},{label:"EURC",value:"EURC"}]},deposit_micro_enabled:{key:"deposit_micro_enabled",label:"SOL Micro Payments",description:"Allow small SOL deposits (under $10) that are batched together for efficiency.",inputType:"boolean"},deposit_gasless_swap_enabled:{key:"deposit_gasless_swap_enabled",label:"Gasless Swap Payments",description:"Allow deposits via Jupiter swaps.",inputType:"boolean"},deposit_min_usd:{key:"deposit_min_usd",label:"Minimum Deposit",description:"Minimum deposit amount in USD equivalent.",inputType:"select",unit:"USD",presets:[{label:"$1",value:"1"},{label:"$5",value:"5"},{label:"$10",value:"10"},{label:"$25",value:"25"}]},deposit_max_usd:{key:"deposit_max_usd",label:"Maximum Deposit",description:"Maximum deposit amount per transaction in USD equivalent. Set to 0 for unlimited.",inputType:"select",unit:"USD",presets:[{label:"Unlimited",value:"0"},{label:"$1,000",value:"1000"},{label:"$10,000",value:"10000"},{label:"$100,000",value:"100000"}]},deposit_show_explainer:{key:"deposit_show_explainer",label:"Show Explainer Screen",description:"Show the introductory explainer screen at the start of the deposit flow.",inputType:"boolean"},deposit_quick_action_tokens:{key:"deposit_quick_action_tokens",label:"Quick Action Tokens",description:"Comma-separated token symbols shown as quick action buttons. First token is the default.",inputType:"tokenSymbolList"},deposit_custom_tokens:{key:"deposit_custom_tokens",label:"Custom Dropdown Tokens",description:'Comma-separated token symbols shown in the "Custom" dropdown. Leave empty to show all.',inputType:"tokenSymbolList"},deposit_custom_tokens_json:{key:"deposit_custom_tokens_json",label:"Custom Token Definitions",description:"Add tokens beyond the built-in list. Define symbol, mint address, decimals, and logo URL.",inputType:"tokenList"},deposit_fee_policy:{key:"deposit_fee_policy",label:"Fee Policy",description:"Who pays deposit fees: company absorbs all, or user pays swap/privacy/all fees.",inputType:"select",presets:[{label:"Company Pays All",value:"company_pays_all"},{label:"User Pays Swap Fees",value:"user_pays_swap"},{label:"User Pays Privacy Fees",value:"user_pays_privacy"},{label:"User Pays All Fees",value:"user_pays_all"}]},privacy_fee_fixed_lamports:{key:"privacy_fee_fixed_lamports",label:"Privacy Fixed Fee",description:"Fixed fee for Privacy Cash deposits in lamports. 1 SOL = 1,000,000,000 lamports.",inputType:"select",unit:"lamports",presets:[{label:"0 SOL",value:"0"},{label:"0.001 SOL",value:"1000000"},{label:"0.005 SOL",value:"5000000"},{label:"0.006 SOL (Default)",value:"6000000"},{label:"0.01 SOL",value:"10000000"}]},privacy_fee_percent_bps:{key:"privacy_fee_percent_bps",label:"Privacy Percentage Fee",description:"Percentage fee for Privacy Cash deposits in basis points. 100 bps = 1%.",inputType:"select",unit:"bps",presets:[{label:"0%",value:"0"},{label:"0.25%",value:"25"},{label:"0.35% (Default)",value:"35"},{label:"0.5%",value:"50"},{label:"1%",value:"100"}]},swap_fee_fixed_lamports:{key:"swap_fee_fixed_lamports",label:"Swap Fixed Fee",description:"Fixed fee for Jupiter swaps in lamports. Covers transaction costs.",inputType:"select",unit:"lamports",presets:[{label:"0 SOL",value:"0"},{label:"0.001 SOL (Default)",value:"1000000"},{label:"0.002 SOL",value:"2000000"},{label:"0.005 SOL",value:"5000000"}]},swap_fee_percent_bps:{key:"swap_fee_percent_bps",label:"Swap Percentage Fee",description:"Percentage fee for Jupiter swaps in basis points. 100 bps = 1%.",inputType:"select",unit:"bps",presets:[{label:"0%",value:"0"},{label:"0.1% (Default)",value:"10"},{label:"0.25%",value:"25"},{label:"0.5%",value:"50"}]},company_fee_fixed_lamports:{key:"company_fee_fixed_lamports",label:"Company Fixed Fee",description:"Additional fixed processing fee in lamports. Set to 0 to disable.",inputType:"select",unit:"lamports",presets:[{label:"Disabled",value:"0"},{label:"0.001 SOL",value:"1000000"},{label:"0.005 SOL",value:"5000000"},{label:"0.01 SOL",value:"10000000"}]},company_fee_percent_bps:{key:"company_fee_percent_bps",label:"Company Percentage Fee",description:"Additional percentage processing fee in basis points. 100 bps = 1%.",inputType:"select",unit:"bps",presets:[{label:"Disabled",value:"0"},{label:"0.1%",value:"10"},{label:"0.25%",value:"25"},{label:"0.5%",value:"50"},{label:"1%",value:"100"}]},micro_batch_threshold_usd:{key:"micro_batch_threshold_usd",label:"Batch Threshold",description:"Minimum accumulated USD value before triggering a batch swap. Jupiter requires ~$10 minimum.",inputType:"select",unit:"USD",presets:[{label:"$10 (Minimum)",value:"10"},{label:"$25",value:"25"},{label:"$50",value:"50"},{label:"$100",value:"100"}]},micro_batch_poll_secs:{key:"micro_batch_poll_secs",label:"Batch Poll Interval",description:"How often to check for batchable micro deposits. Lower values process faster but increase load.",inputType:"duration",min:60,presets:[{label:"1 minute",value:"60"},{label:"5 minutes (Default)",value:"300"},{label:"15 minutes",value:"900"},{label:"1 hour",value:"3600"}]},private_deposit_min_lamports:{key:"private_deposit_min_lamports",label:"Min Private Deposit",description:"Minimum amount for Privacy Cash deposits in lamports. Smaller deposits use micro batching.",inputType:"select",unit:"lamports",presets:[{label:"0.1 SOL",value:"100000000"},{label:"0.25 SOL (Default)",value:"250000000"},{label:"0.5 SOL",value:"500000000"},{label:"1 SOL",value:"1000000000"}]},withdrawal_min_lamports:{key:"withdrawal_min_lamports",label:"Min Withdrawal Amount",description:"Minimum amount to withdraw in lamports. Deposits below this remain pending. Fees are ~0.006 SOL + 0.35% + Jupiter.",inputType:"select",unit:"lamports",presets:[{label:"0.5 SOL",value:"500000000"},{label:"1 SOL (Default)",value:"1000000000"},{label:"2 SOL",value:"2000000000"},{label:"5 SOL",value:"5000000000"}],warningThreshold:{below:5e8,message:"Very small withdrawals may lose significant value to fees."}},sidecar_api_key:{key:"sidecar_api_key",label:"Sidecar API Key",description:"Authenticates requests from cedros-login to the login-sidecar. This value must also be set as the SIDECAR_API_KEY environment variable on the sidecar container.",inputType:"readonlySecret"},note_encryption_key:{key:"note_encryption_key",label:"Note Encryption Key",description:"AES-256 key for encrypting privacy cash notes (base64). This value must also be set as the NOTE_ENCRYPTION_KEY environment variable on the sidecar container.",inputType:"readonlySecret"},postlogin_redirect_url:{key:"postlogin_redirect_url",label:"Redirect URL",description:"URL to redirect to after login. Leave empty for default behavior (consumer app decides).",inputType:"text",placeholder:"https://example.com/dashboard"},postlogin_welcome_enabled:{key:"postlogin_welcome_enabled",label:"Enable Welcome Page",description:"Show a one-time welcome/onboarding page to new users after their first login.",inputType:"boolean"},postlogin_welcome_route:{key:"postlogin_welcome_route",label:"Welcome Route",description:"Route for the welcome/onboarding page.",inputType:"text",placeholder:"/welcome"},postlogin_complete_enabled:{key:"postlogin_complete_enabled",label:"Prompt Profile Completion",description:"Prompt users to fill in missing name or email after login. Shows every login until the user completes or skips.",inputType:"boolean"},postlogin_username_enabled:{key:"postlogin_username_enabled",label:"Require Username Selection",description:"Prompt new users to choose a unique handle-style username (e.g. @swift_falcon_42) after signup. Shows until the user picks a username or skips.",inputType:"boolean"},postlogin_wallet_enroll_enabled:{key:"postlogin_wallet_enroll_enabled",label:"Prompt Wallet Enrollment",description:"Prompt users to enroll an embedded wallet after signup. Requires the Embedded Wallet feature to be enabled.",inputType:"boolean"},wallet_enroll_solana_users:{key:"wallet_enroll_solana_users",label:"Enroll Solana Wallet Users",description:"Also prompt Solana wallet users to enroll an embedded wallet. By default they are skipped since they already have a wallet.",inputType:"boolean"},postlogin_show_recovery_enabled:{key:"postlogin_show_recovery_enabled",label:"Show Recovery Info",description:"Show wallet recovery information screen after account creation. Displays recovery phrase based on the configured recovery mode.",inputType:"boolean"},image_storage_enabled:{key:"image_storage_enabled",label:"Enable Image Storage",description:"Enable S3-compatible object storage for user avatar uploads. When disabled, users cannot upload profile pictures.",inputType:"boolean"},image_storage_provider:{key:"image_storage_provider",label:"Storage Provider",description:"Select your S3-compatible storage provider to auto-fill endpoint and region hints.",inputType:"select",presets:[{label:"DigitalOcean Spaces",value:"digitalocean"},{label:"AWS S3",value:"s3"},{label:"Custom S3-Compatible",value:"custom"}]},image_storage_bucket:{key:"image_storage_bucket",label:"Bucket Name",description:"The name of your S3 bucket or DigitalOcean Space.",inputType:"text",placeholder:"my-app-avatars"},image_storage_region:{key:"image_storage_region",label:"Region",description:"AWS region or DigitalOcean datacenter (e.g., us-east-1, nyc3, ams3).",inputType:"text",placeholder:"us-east-1"},image_storage_endpoint:{key:"image_storage_endpoint",label:"Endpoint URL",description:"S3-compatible endpoint URL. For DigitalOcean Spaces: https://{region}.digitaloceanspaces.com. Leave empty for AWS S3.",inputType:"text",placeholder:"https://nyc3.digitaloceanspaces.com"},image_storage_access_key:{key:"image_storage_access_key",label:"Access Key",description:"S3 access key ID or DigitalOcean Spaces access key.",inputType:"secret"},image_storage_secret_key:{key:"image_storage_secret_key",label:"Secret Key",description:"S3 secret access key or DigitalOcean Spaces secret key.",inputType:"secret"},image_storage_cdn_url:{key:"image_storage_cdn_url",label:"CDN URL (optional)",description:"Custom CDN URL prefix for serving images (e.g., https://cdn.example.com). If empty, images are served directly from the bucket URL.",inputType:"text",placeholder:"https://cdn.example.com"}},E={"auth.apple":{label:"Apple Sign-In",description:"Configure Sign in with Apple OAuth integration.",icon:""},"auth.email":{label:"Email Authentication",description:"Configure email/password authentication settings.",icon:""},"auth.google":{label:"Google Sign-In",description:"Configure Google OAuth integration.",icon:""},"auth.solana":{label:"Solana Wallet Auth",description:"Configure Solana wallet signature authentication.",icon:""},"auth.webauthn":{label:"WebAuthn / Passkeys",description:"Configure FIDO2/WebAuthn passwordless authentication.",icon:""},"auth.instantlink":{label:"Instant Link",description:'Passwordless sign-in via email link. Replaces "Forgot your password?" with a one-time login link instead of a password reset.',icon:""},"deposit.general":{label:"General",description:"Core deposit and credit system configuration.",icon:""},postlogin:{label:"Post-Login",description:"Configure what happens after a user logs in.",icon:""},"postlogin.welcome":{label:"Welcome Page",description:"One-time onboarding page shown to new users after first login.",icon:""},"postlogin.complete":{label:"Profile Completion",description:"Prompt users to fill in missing profile information.",icon:""},"postlogin.username":{label:"Username Selection",description:"Prompt users to choose a unique handle-style username.",icon:""},"postlogin.wallet":{label:"Wallet Enrollment",description:"Prompt users to enroll an embedded wallet after signup.",icon:""},deposit:{label:"Deposit Settings",description:"Configure deposit tokens, fees, and related settings.",icon:""},email:{label:"Email / SMTP",description:"Configure outbound email delivery for verification, password reset, and notifications.",icon:""},features:{label:"Feature Flags",description:"Enable or disable major platform features.",icon:""},privacy:{label:"Privacy Settings",description:"Control the privacy period for deposits. Longer periods provide better timing privacy but delay fund availability.",icon:""},rate_limit:{label:"Rate Limiting",description:"Protect the system from abuse by limiting request rates. Balance security with user experience.",icon:""},security:{label:"Security",description:"Configure CORS, cookies, sessions, and JWT settings.",icon:""},server:{label:"Server",description:"Server infrastructure settings. Some may be overridden by environment variables.",icon:""},webhook:{label:"Webhooks",description:"Configure HTTP webhook notifications for auth events.",icon:""},withdrawal:{label:"Withdrawal Worker",description:"Configure how the automated withdrawal processor handles pending withdrawals. These settings affect throughput and privacy.",icon:""},image_storage:{label:"Image Storage",description:"Configure S3-compatible object storage for user avatars and images.",icon:""}},N=["SOL","USDC","USDT","EURC","USD1","PYUSD","USDH","CASH","BONK","ORE"];function T(t){const s=t.split(/(<a\s[^>]*>.*?<\/a>)/g);return s.length===1?t:s.map((a,n)=>{const l=a.match(/^<a\s+href="([^"]+)"[^>]*>([^<]+)<\/a>$/);return l?e.jsx("a",{href:l[1],target:"_blank",rel:"noopener noreferrer",children:l[2]},n):a})}function O({settings:t,edits:s,onChange:a,externalWarnings:n}){return e.jsx("div",{className:"cedros-settings-grid",children:t.map(l=>e.jsx(I,{setting:l,editValue:s[l.key],onChange:a,externalWarning:n?.[l.key]},l.key))})}function I({setting:t,editValue:s,onChange:a,externalWarning:n}){const l=C[t.key],i=s??t.value,p=s!==void 0&&s!==t.value,r=l?.inputType==="boolean",o=u.useMemo(()=>{if(n)return n;if(!l?.warningThreshold)return null;const c=parseInt(i,10);if(isNaN(c))return null;const{above:m,below:b,message:y}=l.warningThreshold;return m!==void 0&&c>m||b!==void 0&&c<b?y:null},[i,l?.warningThreshold,n]);return l?e.jsx("div",{className:`cedros-setting-row ${p?"cedros-setting-row-changed":""} ${o?"cedros-setting-row-warning":""} ${r?"cedros-setting-row-toggle":""}`,children:r?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"cedros-setting-control cedros-setting-control-toggle",children:[e.jsx(j,{meta:l,value:i,onChange:c=>a(t.key,c)}),o&&e.jsx("div",{className:"cedros-setting-warning",children:o})]}),e.jsxs("div",{className:"cedros-setting-label",children:[e.jsx("span",{className:"cedros-setting-name",children:l.label}),e.jsx("span",{className:"cedros-setting-description",children:T(l.description)})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"cedros-setting-label",children:[e.jsx("span",{className:"cedros-setting-name",children:l.label}),e.jsx("span",{className:"cedros-setting-description",children:T(l.description)})]}),e.jsxs("div",{className:"cedros-setting-control",children:[e.jsx(j,{meta:l,value:i,onChange:c=>a(t.key,c)}),o&&e.jsx("div",{className:"cedros-setting-warning",children:o})]})]})}):e.jsxs("div",{className:`cedros-setting-row ${p?"cedros-setting-row-changed":""}`,children:[e.jsxs("div",{className:"cedros-setting-label",children:[e.jsx("span",{className:"cedros-setting-name",children:t.key}),t.description&&e.jsx("span",{className:"cedros-setting-description",children:t.description})]}),e.jsx("div",{className:"cedros-setting-input-wrapper",children:e.jsx("input",{type:"text",value:i,onChange:c=>a(t.key,c.target.value),className:"cedros-setting-input"})})]})}function j({meta:t,value:s,onChange:a}){switch(t.inputType){case"duration":return e.jsx(U,{value:s,onChange:a,presets:t.presets,min:t.min});case"percentage":return e.jsx(M,{value:s,onChange:a,min:t.min??1,max:t.max??100,step:t.step??5,presets:t.presets});case"select":return e.jsx(F,{value:s,onChange:a,presets:t.presets??[],unit:t.unit});case"number":return e.jsx(W,{value:s,onChange:a,min:t.min,max:t.max,unit:t.unit});case"tokenList":return e.jsx(G,{value:s,onChange:a});case"text":return e.jsx("input",{type:"text",value:s,onChange:n=>a(n.target.value),className:"cedros-setting-input",placeholder:t.label});case"boolean":return e.jsx(q,{value:s,onChange:a});case"secret":return e.jsx($,{value:s,onChange:a,multiline:t.multiline});case"readonlySecret":return e.jsx(B,{settingKey:t.key,value:s});case"tokenSymbolList":return e.jsx(J,{value:s,onChange:a});default:return e.jsx("input",{type:"text",value:s,onChange:n=>a(n.target.value),className:"cedros-setting-input"})}}function U({value:t,onChange:s,presets:a,min:n=0}){const l=parseInt(t,10)||0,i=R(l),p=u.useCallback(o=>{o.target.value&&s(o.target.value)},[s]),r=u.useCallback(o=>{const c=Math.max(n,parseInt(o.target.value,10)||0);s(String(c))},[s,n]);return e.jsxs("div",{className:"cedros-duration-input",children:[a&&a.length>0&&e.jsxs("select",{value:a.find(o=>o.value===t)?.value??"",onChange:p,className:"cedros-setting-select",children:[e.jsx("option",{value:"",children:"Custom..."}),a.map(o=>e.jsx("option",{value:o.value,children:o.label},o.value))]}),e.jsxs("div",{className:"cedros-duration-custom",children:[e.jsx("input",{type:"number",value:l,onChange:r,min:n,className:"cedros-setting-input cedros-setting-input-sm"}),e.jsx("span",{className:"cedros-setting-unit",children:"seconds"}),e.jsxs("span",{className:"cedros-duration-display",children:["= ",i]})]})]})}function M({value:t,onChange:s,min:a,max:n,step:l,presets:i}){const p=parseInt(t,10)||a,r=u.useCallback(c=>{s(c.target.value)},[s]),o=u.useCallback(c=>{s(c)},[s]);return e.jsxs("div",{className:"cedros-percentage-input",children:[e.jsxs("div",{className:"cedros-percentage-slider-row",children:[e.jsx("input",{type:"range",value:p,onChange:r,min:a,max:n,step:l,className:"cedros-percentage-slider"}),e.jsxs("span",{className:"cedros-percentage-value",children:[p,"%"]})]}),i&&i.length>0&&e.jsx("div",{className:"cedros-preset-buttons",children:i.map(c=>e.jsx("button",{type:"button",className:`cedros-preset-button ${c.value===t?"cedros-preset-button-active":""}`,onClick:()=>o(c.value),children:c.label},c.value))})]})}function F({value:t,onChange:s,presets:a,unit:n}){const l=!a.some(r=>r.value===t),i=u.useCallback(r=>{r.target.value!=="__custom__"&&s(r.target.value)},[s]),p=u.useCallback(r=>{s(r.target.value)},[s]);return e.jsxs("div",{className:"cedros-select-input",children:[e.jsxs("select",{value:l?"__custom__":t,onChange:i,className:"cedros-setting-select",children:[a.map(r=>e.jsx("option",{value:r.value,children:r.label},r.value)),e.jsx("option",{value:"__custom__",children:"Custom..."})]}),l&&e.jsxs("div",{className:"cedros-select-custom",children:[e.jsx("input",{type:"number",value:t,onChange:p,className:"cedros-setting-input cedros-setting-input-sm"}),n&&e.jsx("span",{className:"cedros-setting-unit",children:n})]})]})}function W({value:t,onChange:s,min:a,max:n,unit:l}){const i=u.useCallback(p=>{s(p.target.value)},[s]);return e.jsxs("div",{className:"cedros-number-input",children:[e.jsx("input",{type:"number",value:t,onChange:i,min:a,max:n,className:"cedros-setting-input"}),l&&e.jsx("span",{className:"cedros-setting-unit",children:l})]})}function q({value:t,onChange:s}){const a=t==="true",n=u.useCallback(()=>{s(a?"false":"true")},[a,s]);return e.jsxs("button",{type:"button",role:"switch","aria-checked":a,className:`cedros-toggle ${a?"cedros-toggle-on":"cedros-toggle-off"}`,onClick:n,children:[e.jsx("span",{className:"cedros-toggle-track",children:e.jsx("span",{className:"cedros-toggle-thumb"})}),e.jsx("span",{className:"cedros-toggle-label",children:a?"Enabled":"Disabled"})]})}function $({value:t,onChange:s,multiline:a}){const[n,l]=u.useState(!1),[i,p]=u.useState(!1),r=t&&t.length>0,o=u.useCallback(()=>{l(!0),p(!0)},[]),c=u.useCallback(()=>{l(!1),p(!1)},[]),m=u.useCallback(b=>{s(b.target.value)},[s]);return!n&&r?e.jsxs("div",{className:"cedros-secret-input cedros-secret-input-masked",children:[e.jsx("span",{className:"cedros-secret-masked",children:"•".repeat(Math.min(t.length,20))}),e.jsx("button",{type:"button",className:"cedros-secret-edit-btn",onClick:o,children:"Edit"})]}):e.jsxs("div",{className:"cedros-secret-input",children:[a?e.jsx("textarea",{value:t,onChange:m,className:"cedros-setting-input cedros-setting-textarea",placeholder:"Enter secret value...",rows:4}):e.jsx("input",{type:i?"text":"password",value:t,onChange:m,className:"cedros-setting-input",placeholder:"Enter secret value..."}),e.jsxs("div",{className:"cedros-secret-actions",children:[!a&&e.jsx("button",{type:"button",className:"cedros-secret-toggle-btn",onClick:()=>p(!i),children:i?"Hide":"Show"}),n&&e.jsx("button",{type:"button",className:"cedros-secret-done-btn",onClick:c,children:"Done"})]})]})}function B({settingKey:t,value:s}){const[a,n]=u.useState(null),[l,i]=u.useState(!1),[p,r]=u.useState(!1),[o,c]=u.useState(null),[m,b]=u.useState(!1),{config:y,_internal:f}=A.useCedrosLogin(),_=a??s,w=_&&_.length>0,S=w&&!a,h=u.useCallback(async()=>{if(_)try{await navigator.clipboard.writeText(_),i(!0),setTimeout(()=>i(!1),2e3)}catch{const d=document.createElement("textarea");d.value=_,document.body.appendChild(d),d.select(),document.execCommand("copy"),document.body.removeChild(d),i(!0),setTimeout(()=>i(!1),2e3)}},[_]),v=u.useCallback(async()=>{r(!0),c(null);try{const d=f?.getAccessToken?.(),g={"Content-Type":"application/json"};d&&(g.Authorization=`Bearer ${d}`);const k=await fetch(`${y.serverUrl}/auth/admin/settings/regenerate/${t}`,{method:"POST",headers:g,credentials:"include"});if(!k.ok){const x=await k.json().catch(()=>null);throw new Error(x?.message||x?.error||`Regenerate failed (${k.status})`)}const P=await k.json();n(P.value),b(!1)}catch(d){c(d instanceof Error?d.message:"Failed to regenerate")}finally{r(!1)}},[y.serverUrl,f,t]);return e.jsxs("div",{className:"cedros-readonly-secret",children:[e.jsx("div",{className:"cedros-readonly-secret-value",children:S?e.jsx("span",{className:"cedros-secret-masked",children:"•".repeat(20)}):w?e.jsx("code",{className:"cedros-readonly-secret-code",children:_}):e.jsx("span",{className:"cedros-readonly-secret-empty",children:"Not generated yet"})}),e.jsxs("div",{className:"cedros-readonly-secret-actions",children:[w&&e.jsx("button",{type:"button",className:"cedros-secret-action-btn",onClick:h,children:l?"Copied!":"Copy"}),m?e.jsxs("span",{className:"cedros-readonly-secret-confirm",children:[e.jsx("span",{className:"cedros-readonly-secret-confirm-text",children:"Update deploy secret too?"}),e.jsx("button",{type:"button",className:"cedros-secret-action-btn cedros-secret-action-btn--danger",onClick:v,disabled:p,children:p?"Regenerating...":"Confirm"}),e.jsx("button",{type:"button",className:"cedros-secret-action-btn",onClick:()=>b(!1),disabled:p,children:"Cancel"})]}):e.jsx("button",{type:"button",className:"cedros-secret-action-btn cedros-secret-action-btn--danger",onClick:()=>b(!0),disabled:p,children:"Regenerate"})]}),o&&e.jsx("p",{className:"cedros-readonly-secret-error",children:o})]})}function G({value:t,onChange:s}){const a=u.useMemo(()=>{try{return JSON.parse(t||"[]")}catch{return[]}},[t]),n=u.useCallback(r=>{s(JSON.stringify(r))},[s]),l=u.useCallback(()=>{n([...a,{symbol:"",mint:"",decimals:6}])},[a,n]),i=u.useCallback((r,o,c)=>{const m=[...a];m[r]={...m[r],[o]:c},n(m)},[a,n]),p=u.useCallback(r=>{n(a.filter((o,c)=>c!==r))},[a,n]);return e.jsxs("div",{className:"cedros-token-list-input",children:[e.jsxs("div",{className:"cedros-token-presets",children:[e.jsx("span",{className:"cedros-token-presets-label",children:"Built-in tokens:"}),e.jsx("div",{className:"cedros-token-presets-list",children:N.map(r=>e.jsx("span",{className:"cedros-token-preset-chip",children:r},r))})]}),a.length===0&&e.jsx("p",{className:"cedros-token-list-empty",children:"No custom tokens added. Use the built-in tokens above or add your own."}),a.map((r,o)=>e.jsxs("div",{className:"cedros-token-row",children:[e.jsxs("div",{className:"cedros-token-row-fields",children:[e.jsx("input",{type:"text",placeholder:"Symbol",value:r.symbol,onChange:c=>i(o,"symbol",c.target.value.toUpperCase()),className:"cedros-setting-input cedros-token-input-symbol",maxLength:10}),e.jsx("input",{type:"text",placeholder:"Mint address",value:r.mint,onChange:c=>i(o,"mint",c.target.value),className:"cedros-setting-input cedros-token-input-mint"}),e.jsx("input",{type:"number",placeholder:"Decimals",value:r.decimals,onChange:c=>i(o,"decimals",parseInt(c.target.value,10)||0),className:"cedros-setting-input cedros-token-input-decimals",min:0,max:18}),e.jsx("input",{type:"text",placeholder:"Logo URL (optional)",value:r.logoUrl||"",onChange:c=>i(o,"logoUrl",c.target.value||void 0),className:"cedros-setting-input cedros-token-input-logo"})]}),e.jsx("button",{type:"button",className:"cedros-token-remove-btn",onClick:()=>p(o),title:"Remove token",children:"×"})]},o)),e.jsx("button",{type:"button",className:"cedros-token-add-btn",onClick:l,children:"+ Add Token"})]})}function J({value:t,onChange:s}){const a=u.useMemo(()=>t.split(",").map(i=>i.trim()).filter(Boolean),[t]),n=u.useCallback(i=>{if(!i||a.includes(i))return;const p=[...a,i].join(", ");s(p)},[a,s]),l=u.useCallback(i=>{const p=a.filter(r=>r!==i).join(", ");s(p)},[a,s]);return e.jsxs("div",{className:"cedros-token-symbol-list-input",children:[e.jsxs("div",{className:"cedros-token-presets",children:[e.jsx("span",{className:"cedros-token-presets-label",children:"Click to add:"}),e.jsx("div",{className:"cedros-token-presets-list",children:N.map(i=>{const p=a.includes(i);return e.jsxs("button",{type:"button",className:`cedros-token-preset-chip ${p?"cedros-token-preset-chip-selected":""}`,onClick:()=>p?l(i):n(i),title:p?`Remove ${i}`:`Add ${i}`,children:[i,p&&e.jsx("span",{className:"cedros-token-chip-check",children:"✓"})]},i)})})]}),e.jsx("input",{type:"text",value:t,onChange:i=>s(i.target.value),className:"cedros-setting-input",placeholder:"USDC, SOL, BONK..."})]})}const V=800,H=2e3;function K(){const{settings:t,isLoading:s,error:a,fetchSettings:n,updateSettings:l}=L.useSystemSettings(),[i,p]=u.useState({}),[r,o]=u.useState("idle"),[c,m]=u.useState(null),b=u.useRef(null),y=u.useRef(null),f=u.useRef({});u.useEffect(()=>()=>{b.current&&clearTimeout(b.current),y.current&&clearTimeout(y.current)},[]);const _=u.useCallback(async()=>{const h={...f.current};if(Object.keys(h).length===0){o("idle");return}o("saving"),m(null);const v=Object.entries(h).map(([d,g])=>({key:d,value:g}));try{await l(v),p(d=>{const g={...d};for(const k of Object.keys(h))delete g[k];return g});for(const d of Object.keys(h))delete f.current[d];o("saved"),y.current&&clearTimeout(y.current),y.current=setTimeout(()=>{o("idle")},H)}catch(d){o("error"),m(d instanceof Error?d.message:"Failed to save")}},[l]),w=u.useCallback((h,v)=>{p(d=>({...d,[h]:v})),f.current[h]=v,m(null),o("pending"),b.current&&clearTimeout(b.current),b.current=setTimeout(()=>{_()},V)},[_]),S=u.useCallback(h=>{if(i[h]!==void 0)return i[h];for(const v of Object.values(t)){const d=v.find(g=>g.key===h);if(d)return d.value}return""},[i,t]);return{settings:t,edits:i,isLoading:s,autosaveStatus:r,autosaveError:c,error:a,fetchSettings:n,handleChange:w,getEffectiveValue:S}}function Y({status:t,error:s}){return t==="idle"?null:e.jsxs("div",{className:`cedros-autosave-status cedros-autosave-status--${t}`,children:[t==="pending"&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"cedros-autosave-dot"}),e.jsx("span",{children:"Unsaved changes"})]}),t==="saving"&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"cedros-autosave-spinner"}),e.jsx("span",{children:"Saving..."})]}),t==="saved"&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"cedros-autosave-check",children:"✓"}),e.jsx("span",{children:"Saved"})]}),t==="error"&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"cedros-autosave-error-icon",children:"!"}),e.jsx("span",{children:s||"Save failed"})]})]})}exports.AutosaveStatus=Y;exports.CATEGORY_METADATA=E;exports.SETTING_METADATA=C;exports.SettingsSection=O;exports.useSettingsAutosave=K;