@cedros/login-react 0.0.13 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/AdminDepositList-CyT4VBH8.js +311 -0
- package/dist/AdminDepositList-CyT4VBH8.js.map +1 -0
- package/dist/AdminDepositList-b2AXtLg0.cjs +1 -0
- package/dist/AdminDepositList-b2AXtLg0.cjs.map +1 -0
- package/dist/{AdminWithdrawalHistory-BGjfrIe3.js → AdminWithdrawalHistory-Cud-yuWy.js} +295 -283
- package/dist/AdminWithdrawalHistory-Cud-yuWy.js.map +1 -0
- package/dist/AdminWithdrawalHistory-DL9zbu2b.cjs +1 -0
- package/dist/AdminWithdrawalHistory-DL9zbu2b.cjs.map +1 -0
- package/dist/{AuthenticationSettings-5Vi7Ib_A.cjs → AuthenticationSettings-CjGGqbcS.cjs} +1 -1
- package/dist/{AuthenticationSettings-5Vi7Ib_A.cjs.map → AuthenticationSettings-CjGGqbcS.cjs.map} +1 -1
- package/dist/{AuthenticationSettings-CJg8CJY9.js → AuthenticationSettings-DGWktSVw.js} +1 -1
- package/dist/{AuthenticationSettings-CJg8CJY9.js.map → AuthenticationSettings-DGWktSVw.js.map} +1 -1
- package/dist/{AuthenticationSettings-CR_i6TTS.js → AuthenticationSettings-Dg6ATgOl.js} +170 -140
- package/dist/{AuthenticationSettings-CR_i6TTS.js.map → AuthenticationSettings-Dg6ATgOl.js.map} +1 -1
- package/dist/AuthenticationSettings-HhrUAmM6.cjs +1 -0
- package/dist/{AuthenticationSettings-BPAh1my6.cjs.map → AuthenticationSettings-HhrUAmM6.cjs.map} +1 -1
- package/dist/AutosaveStatus-BDWxAg4U.cjs +1 -0
- package/dist/AutosaveStatus-BDWxAg4U.cjs.map +1 -0
- package/dist/{AutosaveStatus-N4uNS6-2.js → AutosaveStatus-DeViUyyI.js} +1 -7
- package/dist/AutosaveStatus-DeViUyyI.js.map +1 -0
- package/dist/{CreditSystemSettings-BnAOK_tT.cjs → CreditSystemSettings-BykhytcS.cjs} +1 -1
- package/dist/{CreditSystemSettings-BnAOK_tT.cjs.map → CreditSystemSettings-BykhytcS.cjs.map} +1 -1
- package/dist/{CreditSystemSettings-CePYGgev.js → CreditSystemSettings-CSlsQynZ.js} +1 -1
- package/dist/{CreditSystemSettings-CePYGgev.js.map → CreditSystemSettings-CSlsQynZ.js.map} +1 -1
- package/dist/{CreditSystemSettings-Ck5WIMp3.cjs → CreditSystemSettings-CyFQbXMh.cjs} +1 -1
- package/dist/{CreditSystemSettings-Ck5WIMp3.cjs.map → CreditSystemSettings-CyFQbXMh.cjs.map} +1 -1
- package/dist/{CreditSystemSettings-CIf_SfJq.js → CreditSystemSettings-DBr7QS59.js} +1 -1
- package/dist/{CreditSystemSettings-CIf_SfJq.js.map → CreditSystemSettings-DBr7QS59.js.map} +1 -1
- package/dist/DepositsSection-BkKUS4vk.cjs +1 -0
- package/dist/DepositsSection-BkKUS4vk.cjs.map +1 -0
- package/dist/{DepositsSection-DA89uR9A.js → DepositsSection-DD9MKUFt.js} +20 -14
- package/dist/DepositsSection-DD9MKUFt.js.map +1 -0
- package/dist/EmailRegisterForm-Pvm3I8GP.cjs +1 -0
- package/dist/{EmailRegisterForm-CxktR-4J.cjs.map → EmailRegisterForm-Pvm3I8GP.cjs.map} +1 -1
- package/dist/{EmailRegisterForm-BrDL3BZy.js → EmailRegisterForm-nI0BOIxR.js} +2 -2
- package/dist/{EmailRegisterForm-BrDL3BZy.js.map → EmailRegisterForm-nI0BOIxR.js.map} +1 -1
- package/dist/{EmailSettings-DZywTTRq.cjs → EmailSettings-Bup2rCgU.cjs} +1 -1
- package/dist/{EmailSettings-DZywTTRq.cjs.map → EmailSettings-Bup2rCgU.cjs.map} +1 -1
- package/dist/{EmailSettings-Bna7Z53E.js → EmailSettings-C04qdJCz.js} +1 -1
- package/dist/{EmailSettings-Bna7Z53E.js.map → EmailSettings-C04qdJCz.js.map} +1 -1
- package/dist/{EmailSettings-B8xwgd6_.cjs → EmailSettings-C0Ss6Cne.cjs} +1 -1
- package/dist/{EmailSettings-B8xwgd6_.cjs.map → EmailSettings-C0Ss6Cne.cjs.map} +1 -1
- package/dist/{EmailSettings-DbMDfVaM.js → EmailSettings-DAqH_xum.js} +1 -1
- package/dist/{EmailSettings-DbMDfVaM.js.map → EmailSettings-DAqH_xum.js.map} +1 -1
- package/dist/{EmbeddedWalletSettings-DivEPn39.cjs → EmbeddedWalletSettings-B0XkNuPR.cjs} +1 -1
- package/dist/{EmbeddedWalletSettings-DivEPn39.cjs.map → EmbeddedWalletSettings-B0XkNuPR.cjs.map} +1 -1
- package/dist/{EmbeddedWalletSettings-ANbhj3Lt.js → EmbeddedWalletSettings-DDFQhQOw.js} +1 -1
- package/dist/{EmbeddedWalletSettings-ANbhj3Lt.js.map → EmbeddedWalletSettings-DDFQhQOw.js.map} +1 -1
- package/dist/{EmbeddedWalletSettings-BEztqO19.js → EmbeddedWalletSettings-DYh884HP.js} +1 -1
- package/dist/{EmbeddedWalletSettings-BEztqO19.js.map → EmbeddedWalletSettings-DYh884HP.js.map} +1 -1
- package/dist/{EmbeddedWalletSettings-D6M7pwgk.cjs → EmbeddedWalletSettings-YX0Dk_b_.cjs} +1 -1
- package/dist/{EmbeddedWalletSettings-D6M7pwgk.cjs.map → EmbeddedWalletSettings-YX0Dk_b_.cjs.map} +1 -1
- package/dist/{GoogleLoginButton-B3uRMJ_n.js → GoogleLoginButton-CXwp4LsQ.js} +1 -1
- package/dist/{GoogleLoginButton-B3uRMJ_n.js.map → GoogleLoginButton-CXwp4LsQ.js.map} +1 -1
- package/dist/GoogleLoginButton-zS_69-KV.cjs +1 -0
- package/dist/{GoogleLoginButton-BydKswn4.cjs.map → GoogleLoginButton-zS_69-KV.cjs.map} +1 -1
- package/dist/PermissionsSection-BPbE-hNx.cjs +1 -0
- package/dist/{PermissionsSection-CKXXDfqi.cjs.map → PermissionsSection-BPbE-hNx.cjs.map} +1 -1
- package/dist/{PermissionsSection-BGaj_sI7.js → PermissionsSection-CighC1p6.js} +3 -3
- package/dist/{PermissionsSection-BGaj_sI7.js.map → PermissionsSection-CighC1p6.js.map} +1 -1
- package/dist/{ServerSettings-BZXlm1BX.cjs → ServerSettings-CInJe4jY.cjs} +1 -1
- package/dist/{ServerSettings-BZXlm1BX.cjs.map → ServerSettings-CInJe4jY.cjs.map} +1 -1
- package/dist/{ServerSettings-DZUKo6By.cjs → ServerSettings-CwnEI-PC.cjs} +1 -1
- package/dist/{ServerSettings-DZUKo6By.cjs.map → ServerSettings-CwnEI-PC.cjs.map} +1 -1
- package/dist/{ServerSettings-Bqm4-bt2.js → ServerSettings-DVEtfDQo.js} +1 -1
- package/dist/{ServerSettings-Bqm4-bt2.js.map → ServerSettings-DVEtfDQo.js.map} +1 -1
- package/dist/{ServerSettings-B2RKhJtZ.js → ServerSettings-DakhpYcO.js} +1 -1
- package/dist/{ServerSettings-B2RKhJtZ.js.map → ServerSettings-DakhpYcO.js.map} +1 -1
- package/dist/{SettingsPageLayout-COSYLMu7.cjs → SettingsPageLayout-C6DWgyXS.cjs} +1 -1
- package/dist/{SettingsPageLayout-COSYLMu7.cjs.map → SettingsPageLayout-C6DWgyXS.cjs.map} +1 -1
- package/dist/{SettingsPageLayout-DpgNEkuu.js → SettingsPageLayout-CLJI6hFQ.js} +1 -1
- package/dist/{SettingsPageLayout-DpgNEkuu.js.map → SettingsPageLayout-CLJI6hFQ.js.map} +1 -1
- package/dist/SolanaLoginButton-BjOxpE1C.cjs +1 -0
- package/dist/{SolanaLoginButton-fAW7kRUu.cjs.map → SolanaLoginButton-BjOxpE1C.cjs.map} +1 -1
- package/dist/{SolanaLoginButton-C_u9OppS.js → SolanaLoginButton-P22QjBaO.js} +1 -1
- package/dist/{SolanaLoginButton-C_u9OppS.js.map → SolanaLoginButton-P22QjBaO.js.map} +1 -1
- package/dist/{TeamSection-CvrCoa9D.js → TeamSection-BIECkp7g.js} +2 -2
- package/dist/{TeamSection-CvrCoa9D.js.map → TeamSection-BIECkp7g.js.map} +1 -1
- package/dist/{TeamSection-DlUD5kp5.cjs → TeamSection-BOH9pv_E.cjs} +1 -1
- package/dist/{TeamSection-DlUD5kp5.cjs.map → TeamSection-BOH9pv_E.cjs.map} +1 -1
- package/dist/UsersSection-e6q7FHzx.cjs +1 -0
- package/dist/UsersSection-e6q7FHzx.cjs.map +1 -0
- package/dist/UsersSection-t-zm0jZW.js +33 -0
- package/dist/UsersSection-t-zm0jZW.js.map +1 -0
- package/dist/{WebhookSettings-DXNH5bal.cjs → WebhookSettings-BMeykdRP.cjs} +1 -1
- package/dist/{WebhookSettings-DXNH5bal.cjs.map → WebhookSettings-BMeykdRP.cjs.map} +1 -1
- package/dist/{WebhookSettings-BWl_wsvg.cjs → WebhookSettings-BNVooF0B.cjs} +1 -1
- package/dist/{WebhookSettings-BWl_wsvg.cjs.map → WebhookSettings-BNVooF0B.cjs.map} +1 -1
- package/dist/{WebhookSettings-BT5q6AZ8.js → WebhookSettings-DXeDYhAe.js} +1 -1
- package/dist/{WebhookSettings-BT5q6AZ8.js.map → WebhookSettings-DXeDYhAe.js.map} +1 -1
- package/dist/{WebhookSettings-bUg2u_p0.js → WebhookSettings-DdbxNPZ9.js} +1 -1
- package/dist/{WebhookSettings-bUg2u_p0.js.map → WebhookSettings-DdbxNPZ9.js.map} +1 -1
- package/dist/WithdrawalsSection-sljIyeaz.cjs +1 -0
- package/dist/WithdrawalsSection-sljIyeaz.cjs.map +1 -0
- package/dist/WithdrawalsSection-yRDTVFsb.js +27 -0
- package/dist/WithdrawalsSection-yRDTVFsb.js.map +1 -0
- package/dist/admin-only.cjs +1 -1
- package/dist/admin-only.js +1 -1
- package/dist/email-only.cjs +1 -1
- package/dist/email-only.d.ts +13 -2
- package/dist/email-only.js +3 -3
- package/dist/google-only.cjs +1 -1
- package/dist/google-only.d.ts +13 -2
- package/dist/google-only.js +3 -3
- package/dist/index.cjs +12 -12
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +31 -8
- package/dist/index.js +1066 -1098
- package/dist/index.js.map +1 -1
- package/dist/{plugin-5qRh-YhX.js → plugin-CW_ycXye.js} +1 -1
- package/dist/{plugin-5qRh-YhX.js.map → plugin-CW_ycXye.js.map} +1 -1
- package/dist/{plugin-BtYBW6JY.cjs → plugin-CnbFRy5o.cjs} +1 -1
- package/dist/{plugin-BtYBW6JY.cjs.map → plugin-CnbFRy5o.cjs.map} +1 -1
- package/dist/{shamir-AeLLfw0p.cjs → shamir-4DyQMJCk.cjs} +1 -1
- package/dist/{shamir-AeLLfw0p.cjs.map → shamir-4DyQMJCk.cjs.map} +1 -1
- package/dist/{shamir-B0wConeK.js → shamir-L-s-Tp1Z.js} +1 -1
- package/dist/{shamir-B0wConeK.js.map → shamir-L-s-Tp1Z.js.map} +1 -1
- package/dist/silentWalletEnroll-BgTb4H5I.cjs +1 -0
- package/dist/{silentWalletEnroll-B8pgdKZO.cjs.map → silentWalletEnroll-BgTb4H5I.cjs.map} +1 -1
- package/dist/{silentWalletEnroll-DR2kPw7W.js → silentWalletEnroll-DWt6Pr3B.js} +3 -3
- package/dist/{silentWalletEnroll-DR2kPw7W.js.map → silentWalletEnroll-DWt6Pr3B.js.map} +1 -1
- package/dist/solana-only.cjs +1 -1
- package/dist/solana-only.d.ts +13 -2
- package/dist/solana-only.js +3 -3
- package/dist/{useAdminDeposits-BDY5KJ0-.js → useAdminDeposits-BTSyeAfg.js} +1 -1
- package/dist/{useAdminDeposits-BDY5KJ0-.js.map → useAdminDeposits-BTSyeAfg.js.map} +1 -1
- package/dist/useAdminDeposits-BkkCwHWp.cjs +1 -0
- package/dist/{useAdminDeposits-Dvx3_UUE.cjs.map → useAdminDeposits-BkkCwHWp.cjs.map} +1 -1
- package/dist/{useAuth-Bge6KaWN.js → useAuth-C3dpk0po.js} +597 -561
- package/dist/useAuth-C3dpk0po.js.map +1 -0
- package/dist/useAuth-D3Pk_H3z.cjs +1 -0
- package/dist/useAuth-D3Pk_H3z.cjs.map +1 -0
- package/dist/useCedrosLogin-C9MrcZvh.cjs +1 -0
- package/dist/useCedrosLogin-C9MrcZvh.cjs.map +1 -0
- package/dist/{apiClient-B2JxVPlH.js → useCedrosLogin-_94MmGGq.js} +29 -29
- package/dist/useCedrosLogin-_94MmGGq.js.map +1 -0
- package/dist/{useOrgs-Be3KH4ib.js → useOrgs-C3pzMA9h.js} +1 -1
- package/dist/{useOrgs-Be3KH4ib.js.map → useOrgs-C3pzMA9h.js.map} +1 -1
- package/dist/useOrgs-DDVRCaVi.cjs +1 -0
- package/dist/{useOrgs-CVbacmaQ.cjs.map → useOrgs-DDVRCaVi.cjs.map} +1 -1
- package/dist/{useSystemSettings-DN5YqfNq.js → useSystemSettings-DBlAMjFi.js} +1 -1
- package/dist/{useSystemSettings-DN5YqfNq.js.map → useSystemSettings-DBlAMjFi.js.map} +1 -1
- package/dist/useSystemSettings-DRrreszl.cjs +1 -0
- package/dist/{useSystemSettings-D9Cr7ZTl.cjs.map → useSystemSettings-DRrreszl.cjs.map} +1 -1
- package/dist/useUsersStatsSummary-8qY7iP4G.cjs +1 -0
- package/dist/useUsersStatsSummary-8qY7iP4G.cjs.map +1 -0
- package/dist/{AdminUserDetail-DHFDzY8B.js → useUsersStatsSummary-NjEFvWuz.js} +431 -380
- package/dist/useUsersStatsSummary-NjEFvWuz.js.map +1 -0
- package/package.json +1 -1
- package/dist/AdminDepositList-Cx0xRwES.js +0 -305
- package/dist/AdminDepositList-Cx0xRwES.js.map +0 -1
- package/dist/AdminDepositList-UEcyRZkA.cjs +0 -1
- package/dist/AdminDepositList-UEcyRZkA.cjs.map +0 -1
- package/dist/AdminUserDetail-BzEIdNJh.cjs +0 -1
- package/dist/AdminUserDetail-BzEIdNJh.cjs.map +0 -1
- package/dist/AdminUserDetail-DHFDzY8B.js.map +0 -1
- package/dist/AdminWithdrawalHistory-0yxtMh6q.cjs +0 -1
- package/dist/AdminWithdrawalHistory-0yxtMh6q.cjs.map +0 -1
- package/dist/AdminWithdrawalHistory-BGjfrIe3.js.map +0 -1
- package/dist/AuthenticationSettings-BPAh1my6.cjs +0 -1
- package/dist/AutosaveStatus-CYkC2aI_.cjs +0 -1
- package/dist/AutosaveStatus-CYkC2aI_.cjs.map +0 -1
- package/dist/AutosaveStatus-N4uNS6-2.js.map +0 -1
- package/dist/DepositsSection-DA89uR9A.js.map +0 -1
- package/dist/DepositsSection-i6XdhLNs.cjs +0 -1
- package/dist/DepositsSection-i6XdhLNs.cjs.map +0 -1
- package/dist/EmailRegisterForm-CxktR-4J.cjs +0 -1
- package/dist/GoogleLoginButton-BydKswn4.cjs +0 -1
- package/dist/PermissionsSection-CKXXDfqi.cjs +0 -1
- package/dist/SolanaLoginButton-fAW7kRUu.cjs +0 -1
- package/dist/UsersSection-C2U8Tb7V.cjs +0 -1
- package/dist/UsersSection-C2U8Tb7V.cjs.map +0 -1
- package/dist/UsersSection-Dbh9PTSA.js +0 -83
- package/dist/UsersSection-Dbh9PTSA.js.map +0 -1
- package/dist/WithdrawalsSection-BL_LOUq8.cjs +0 -1
- package/dist/WithdrawalsSection-BL_LOUq8.cjs.map +0 -1
- package/dist/WithdrawalsSection-CN-lLnqX.js +0 -20
- package/dist/WithdrawalsSection-CN-lLnqX.js.map +0 -1
- package/dist/apiClient-B2JxVPlH.js.map +0 -1
- package/dist/apiClient-CTTKhsYb.cjs +0 -1
- package/dist/apiClient-CTTKhsYb.cjs.map +0 -1
- package/dist/silentWalletEnroll-B8pgdKZO.cjs +0 -1
- package/dist/useAdminDeposits-Dvx3_UUE.cjs +0 -1
- package/dist/useAuth-Bge6KaWN.js.map +0 -1
- package/dist/useAuth-DhIDTLRd.cjs +0 -1
- package/dist/useAuth-DhIDTLRd.cjs.map +0 -1
- package/dist/useOrgs-CVbacmaQ.cjs +0 -1
- package/dist/useSystemSettings-D9Cr7ZTl.cjs +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AdminWithdrawalHistory-BGjfrIe3.js","sources":["../src/components/deposit/admin/AdminWithdrawalStats.tsx","../src/components/deposit/admin/AdminWithdrawalQueue.tsx","../src/components/deposit/admin/AdminPrivacyPeriodDeposits.tsx","../src/components/deposit/admin/AdminWithdrawalHistory.tsx"],"sourcesContent":["/**\n * Admin withdrawal statistics component\n *\n * Shows high-level withdrawal pipeline stats in a single row.\n */\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { useAdminDeposits } from '../../../hooks/useAdminDeposits';\nimport type { AdminDepositStatsResponse } from '../../../types/deposit';\nimport { FeatureDisabledMessage } from './FeatureDisabledMessage';\nimport { isFeatureDisabledError } from './featureDisabled';\nimport { StatsBar } from '../../admin/StatsBar';\n\nexport interface AdminWithdrawalStatsProps {\n /** Auto-refresh interval in milliseconds (0 to disable) */\n refreshInterval?: number;\n /** Additional CSS classes */\n className?: string;\n /** Callback when stats are loaded */\n onLoad?: (stats: AdminDepositStatsResponse) => void;\n}\n\nexport function AdminWithdrawalStats({\n refreshInterval = 0,\n className = '',\n onLoad,\n}: AdminWithdrawalStatsProps) {\n const { getStats, isLoading, error, clearError } = useAdminDeposits();\n\n const [stats, setStats] = useState<AdminDepositStatsResponse | null>(null);\n const [loadError, setLoadError] = useState<string | null>(null);\n\n const fetchStats = useCallback(async () => {\n try {\n const result = await getStats();\n setStats(result);\n onLoad?.(result);\n setLoadError(null);\n } catch (err) {\n const message =\n err && typeof err === 'object' && 'message' in err\n ? String((err as { message: unknown }).message)\n : 'Failed to load stats';\n setLoadError(message);\n }\n }, [getStats, onLoad]);\n\n useEffect(() => {\n fetchStats();\n }, [fetchStats]);\n\n useEffect(() => {\n if (refreshInterval <= 0) return;\n const interval = setInterval(fetchStats, refreshInterval);\n return () => clearInterval(interval);\n }, [refreshInterval, fetchStats]);\n\n const errorMessage = loadError || error;\n if (isFeatureDisabledError(errorMessage)) {\n return <FeatureDisabledMessage feature=\"Privacy Cash\" className={className} />;\n }\n\n if (errorMessage) {\n return (\n <div className={`cedros-admin-stats ${className}`}>\n <p className=\"cedros-admin-error\">{errorMessage}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline\"\n onClick={() => {\n clearError();\n setLoadError(null);\n fetchStats();\n }}\n >\n Retry\n </button>\n </div>\n );\n }\n\n if (isLoading && !stats) {\n return (\n <div className={`cedros-admin-stats ${className}`}>\n <StatsBar\n stats={[\n { label: 'Total Withdrawn', value: 0 },\n { label: 'Pending Withdraw', value: 0 },\n { label: 'In Privacy Period', value: 0 },\n { label: 'Microbatch (SOL)', value: '0.0000' },\n ]}\n isLoading\n />\n </div>\n );\n }\n\n if (!stats) return null;\n\n return (\n <div className={`cedros-admin-stats ${className}`}>\n <StatsBar\n stats={[\n { label: 'Total Withdrawn', value: stats.totalWithdrawnCount },\n { label: 'Pending Withdraw', value: stats.pendingWithdrawalCount },\n { label: 'In Privacy Period', value: stats.inPrivacyPeriodCount ?? 0 },\n { label: 'Microbatch (SOL)', value: stats.readyForWithdrawalSol?.toFixed(4) ?? '0.0000' },\n ]}\n isLoading={isLoading}\n onRefresh={fetchStats}\n />\n </div>\n );\n}\n","/**\n * Admin withdrawal queue component\n *\n * Shows deposits that are ready for withdrawal (privacy period elapsed).\n * Includes buttons to process individual or all withdrawals.\n * Requires system admin privileges.\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useAdminDeposits } from '../../../hooks/useAdminDeposits';\nimport type {\n AdminDepositItem,\n AdminDepositListResponse,\n ProcessWithdrawalResponse,\n ProcessAllWithdrawalsResponse,\n} from '../../../types/deposit';\nimport { FeatureDisabledMessage } from './FeatureDisabledMessage';\nimport { isFeatureDisabledError } from './featureDisabled';\n\ntype QueueSortField = 'userId' | 'amountLamports' | 'withdrawalAvailableAt';\ntype SortOrder = 'asc' | 'desc';\n\nexport interface AdminWithdrawalQueueProps {\n /** Number of items per page (default: 20) */\n pageSize?: number;\n /** Auto-refresh interval in milliseconds (0 to disable) */\n refreshInterval?: number;\n /** Additional CSS classes */\n className?: string;\n /** Callback when list is loaded */\n onLoad?: (response: AdminDepositListResponse) => void;\n /** Callback when a withdrawal item is clicked */\n onItemClick?: (item: AdminDepositItem) => void;\n /** Callback when a withdrawal is processed */\n onWithdrawalProcessed?: (response: ProcessWithdrawalResponse) => void;\n /** Callback when all withdrawals are processed */\n onAllProcessed?: (response: ProcessAllWithdrawalsResponse) => void;\n}\n\nfunction formatAmount(lamports: number | null): string {\n if (lamports === null || lamports === undefined) return '—';\n const solAmount = lamports / 1_000_000_000;\n return `${solAmount.toFixed(4)} SOL`;\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 hour: '2-digit',\n minute: '2-digit',\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 getTimeElapsed(dateString: string): string {\n const date = new Date(dateString);\n const now = new Date();\n const diffMs = now.getTime() - date.getTime();\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMins / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffDays > 0) return `${diffDays}d ago`;\n if (diffHours > 0) return `${diffHours}h ago`;\n if (diffMins > 0) return `${diffMins}m ago`;\n return 'just now';\n}\n\nfunction isWithinPrivacyPeriod(withdrawalAvailableAt: string | undefined): boolean {\n if (!withdrawalAvailableAt) return true;\n return new Date(withdrawalAvailableAt) > new Date();\n}\n\n/**\n * Admin withdrawal queue display\n *\n * Shows deposits ready for withdrawal processing with action buttons.\n */\nexport function AdminWithdrawalQueue({\n pageSize = 20,\n refreshInterval = 0,\n className = '',\n onLoad,\n onItemClick,\n onWithdrawalProcessed,\n onAllProcessed,\n}: AdminWithdrawalQueueProps) {\n const {\n listPendingWithdrawals,\n processWithdrawal,\n processAllWithdrawals,\n isLoading,\n error,\n clearError,\n } = useAdminDeposits();\n\n const [items, setItems] = useState<AdminDepositItem[]>([]);\n const [total, setTotal] = useState(0);\n const [offset, setOffset] = useState(0);\n const [loadError, setLoadError] = useState<string | null>(null);\n const [sortField, setSortField] = useState<QueueSortField>('withdrawalAvailableAt');\n const [sortOrder, setSortOrder] = useState<SortOrder>('asc');\n\n const toggleSort = (field: QueueSortField) => {\n if (sortField === field) {\n setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');\n } else {\n setSortField(field);\n setSortOrder(field === 'withdrawalAvailableAt' ? 'asc' : 'desc');\n }\n };\n\n const sortedItems = useMemo(() => {\n return [...items].sort((a, b) => {\n let aVal: string | number;\n let bVal: string | number;\n\n switch (sortField) {\n case 'userId':\n aVal = a.userId.toLowerCase();\n bVal = b.userId.toLowerCase();\n break;\n case 'amountLamports':\n aVal = a.amountLamports ?? 0;\n bVal = b.amountLamports ?? 0;\n break;\n case 'withdrawalAvailableAt':\n aVal = a.withdrawalAvailableAt ? new Date(a.withdrawalAvailableAt).getTime() : 0;\n bVal = b.withdrawalAvailableAt ? new Date(b.withdrawalAvailableAt).getTime() : 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 }, [items, sortField, sortOrder]);\n\n // Processing state\n const [processingId, setProcessingId] = useState<string | null>(null);\n const [processingAll, setProcessingAll] = useState(false);\n const [processResult, setProcessResult] = useState<{\n type: 'success' | 'error';\n message: string;\n } | null>(null);\n\n // Early withdrawal confirmation modal\n const [earlyWithdrawalItem, setEarlyWithdrawalItem] = useState<AdminDepositItem | null>(null);\n\n const fetchItems = useCallback(async () => {\n try {\n const result = await listPendingWithdrawals({ limit: pageSize, offset });\n setItems(result.deposits);\n setTotal(result.total);\n onLoad?.(result);\n setLoadError(null);\n } catch (err) {\n const message =\n err && typeof err === 'object' && 'message' in err\n ? String((err as { message: unknown }).message)\n : 'Failed to load pending withdrawals';\n setLoadError(message);\n }\n }, [pageSize, offset, listPendingWithdrawals, 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 fetchItems();\n }, [fetchItems]);\n\n // Auto-refresh\n useEffect(() => {\n if (refreshInterval <= 0) return;\n\n const interval = setInterval(fetchItems, refreshInterval);\n return () => clearInterval(interval);\n }, [refreshInterval, fetchItems]);\n\n // Clear result message after 5 seconds\n useEffect(() => {\n if (!processResult) return;\n const timer = setTimeout(() => setProcessResult(null), 5000);\n return () => clearTimeout(timer);\n }, [processResult]);\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 const handleProcessSingle = async (item: AdminDepositItem, force = false) => {\n // Check if within privacy period and not forcing\n if (!force && isWithinPrivacyPeriod(item.withdrawalAvailableAt)) {\n setEarlyWithdrawalItem(item);\n return;\n }\n\n setProcessingId(item.id);\n setProcessResult(null);\n\n try {\n const result = await processWithdrawal(item.id, { force });\n if (result.success) {\n setProcessResult({\n type: 'success',\n message: `Withdrawal processed: ${result.txSignature?.slice(0, 12)}...`,\n });\n onWithdrawalProcessed?.(result);\n // Refresh the list\n await fetchItems();\n } else {\n setProcessResult({\n type: 'error',\n message: result.error || 'Failed to process withdrawal',\n });\n }\n } catch (err) {\n setProcessResult({\n type: 'error',\n message: err instanceof Error ? err.message : 'Failed to process withdrawal',\n });\n } finally {\n setProcessingId(null);\n setEarlyWithdrawalItem(null);\n }\n };\n\n const handleProcessAll = async () => {\n if (items.length === 0) return;\n\n setProcessingAll(true);\n setProcessResult(null);\n\n try {\n const result = await processAllWithdrawals();\n if (result.totalSucceeded > 0) {\n setProcessResult({\n type: 'success',\n message: `Processed ${result.totalSucceeded}/${result.totalProcessed} withdrawals`,\n });\n } else if (result.totalFailed > 0) {\n setProcessResult({\n type: 'error',\n message: `Failed to process ${result.totalFailed} withdrawals`,\n });\n }\n onAllProcessed?.(result);\n // Refresh the list\n await fetchItems();\n } catch (err) {\n setProcessResult({\n type: 'error',\n message: err instanceof Error ? err.message : 'Failed to process withdrawals',\n });\n } finally {\n setProcessingAll(false);\n }\n };\n\n // Feature disabled state\n const errorMessage = loadError || error;\n if (isFeatureDisabledError(errorMessage)) {\n return <FeatureDisabledMessage feature=\"Privacy Cash\" className={className} />;\n }\n\n // Error state\n if (errorMessage) {\n return (\n <div\n className={`cedros-admin-withdrawal-queue cedros-admin-withdrawal-queue-error ${className}`}\n >\n <p className=\"cedros-admin-error\">{errorMessage}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline\"\n onClick={() => {\n clearError();\n setLoadError(null);\n fetchItems();\n }}\n >\n Retry\n </button>\n </div>\n );\n }\n\n // Loading state (initial load only)\n if (isLoading && items.length === 0 && !processingId && !processingAll) {\n return (\n <div\n className={`cedros-admin-withdrawal-queue cedros-admin-withdrawal-queue-loading ${className}`}\n >\n <span className=\"cedros-admin-loading-indicator\" />\n <span className=\"cedros-admin-loading-text\">Loading withdrawal queue...</span>\n </div>\n );\n }\n\n return (\n <div className={`cedros-admin-withdrawal-queue ${className}`}>\n {/* Early Withdrawal Confirmation Modal */}\n {earlyWithdrawalItem && (\n <div\n className=\"cedros-admin-modal-overlay\"\n onClick={() => setEarlyWithdrawalItem(null)}\n onKeyDown={(e) => e.key === 'Escape' && setEarlyWithdrawalItem(null)}\n role=\"dialog\"\n aria-modal=\"true\"\n aria-labelledby=\"early-withdrawal-title\"\n >\n <div\n className=\"cedros-admin-modal cedros-admin-modal-warning\"\n onClick={(e) => e.stopPropagation()}\n onKeyDown={() => {}}\n role=\"document\"\n >\n <h3 id=\"early-withdrawal-title\" className=\"cedros-admin-modal-title\">\n Early Withdrawal Warning\n </h3>\n <div className=\"cedros-admin-modal-content\">\n <p className=\"cedros-admin-modal-warning-text\">\n <strong>This deposit is still within its privacy period.</strong>\n </p>\n <p>\n Processing this withdrawal early may compromise user privacy. The privacy period\n exists to provide plausible deniability for deposits.\n </p>\n <p className=\"cedros-admin-modal-details\">\n User: {truncateId(earlyWithdrawalItem.userId)}\n <br />\n Amount: {formatAmount(earlyWithdrawalItem.amountLamports)}\n <br />\n Available at:{' '}\n {earlyWithdrawalItem.withdrawalAvailableAt\n ? formatDate(earlyWithdrawalItem.withdrawalAvailableAt)\n : '—'}\n </p>\n <p>Are you sure you want to process this withdrawal early?</p>\n </div>\n <div className=\"cedros-admin-modal-actions\">\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline\"\n onClick={() => setEarlyWithdrawalItem(null)}\n >\n Cancel\n </button>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-danger\"\n onClick={() => handleProcessSingle(earlyWithdrawalItem, true)}\n disabled={processingId === earlyWithdrawalItem.id}\n >\n {processingId === earlyWithdrawalItem.id ? 'Processing...' : 'Process Early'}\n </button>\n </div>\n </div>\n </div>\n )}\n\n {/* Result message */}\n {processResult && (\n <div\n className={`cedros-admin-result cedros-admin-result-${processResult.type}`}\n role=\"status\"\n aria-live=\"polite\"\n >\n {processResult.message}\n </div>\n )}\n\n <div className=\"cedros-admin-withdrawal-queue-header\">\n <h4 className=\"cedros-admin-withdrawal-queue-title\">Pending Withdrawals</h4>\n <div className=\"cedros-admin-withdrawal-queue-actions\">\n <span className=\"cedros-admin-queue-count\">{total} pending</span>\n <button\n type=\"button\"\n className=\"cedros-admin__stats-bar-refresh\"\n onClick={fetchItems}\n disabled={isLoading || processingAll}\n title=\"Refresh queue\"\n aria-label=\"Refresh queue\"\n >\n {isLoading && !processingAll ? '...' : '↻'}\n </button>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-primary cedros-button-sm\"\n onClick={handleProcessAll}\n disabled={isLoading || processingAll || items.length === 0}\n title=\"Process all ready withdrawals\"\n >\n {processingAll ? 'Processing...' : 'Process All'}\n </button>\n </div>\n </div>\n\n {items.length === 0 ? (\n <div className=\"cedros-admin-empty\">\n <p className=\"cedros-admin-empty-message\">No pending withdrawals.</p>\n </div>\n ) : (\n <>\n <div className=\"cedros-admin-withdrawal-table\">\n <div className=\"cedros-admin-withdrawal-thead\">\n <div className=\"cedros-admin-withdrawal-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'userId' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('userId')}\n aria-label=\"Sort by user\"\n >\n User{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'userId' ? (sortOrder === 'asc' ? '↑' : '↓') : '↕'}\n </span>\n </button>\n </div>\n <div className=\"cedros-admin-withdrawal-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'amountLamports' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('amountLamports')}\n aria-label=\"Sort by amount\"\n >\n Amount{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'amountLamports' ? (sortOrder === 'asc' ? '↑' : '↓') : '↕'}\n </span>\n </button>\n </div>\n <div className=\"cedros-admin-withdrawal-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'withdrawalAvailableAt' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('withdrawalAvailableAt')}\n aria-label=\"Sort by ready since\"\n >\n Ready Since{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'withdrawalAvailableAt'\n ? sortOrder === 'asc'\n ? '↑'\n : '↓'\n : '↕'}\n </span>\n </button>\n </div>\n <div className=\"cedros-admin-withdrawal-th\">Waiting</div>\n <div className=\"cedros-admin-withdrawal-th cedros-admin-withdrawal-th-action\">\n Action\n </div>\n </div>\n {sortedItems.map((item) => {\n const withinPrivacyPeriod = isWithinPrivacyPeriod(item.withdrawalAvailableAt);\n const isProcessing = processingId === item.id;\n\n return (\n <div\n key={item.id}\n className={`cedros-admin-withdrawal-row ${withinPrivacyPeriod ? 'cedros-admin-withdrawal-row-early' : ''}`}\n onClick={() => onItemClick?.(item)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onItemClick?.(item);\n }\n }}\n role={onItemClick ? 'button' : undefined}\n tabIndex={onItemClick ? 0 : undefined}\n >\n <div className=\"cedros-admin-withdrawal-td\" title={item.userId}>\n {truncateId(item.userId)}\n </div>\n <div className=\"cedros-admin-withdrawal-td\">\n {formatAmount(item.amountLamports)}\n </div>\n <div className=\"cedros-admin-withdrawal-td\">\n {item.withdrawalAvailableAt ? formatDate(item.withdrawalAvailableAt) : '—'}\n </div>\n <div className=\"cedros-admin-withdrawal-td cedros-admin-withdrawal-waiting\">\n {item.withdrawalAvailableAt\n ? withinPrivacyPeriod\n ? 'In privacy period'\n : getTimeElapsed(item.withdrawalAvailableAt)\n : '—'}\n </div>\n <div className=\"cedros-admin-withdrawal-td cedros-admin-withdrawal-td-action\">\n <button\n type=\"button\"\n className={`cedros-button cedros-button-sm ${withinPrivacyPeriod ? 'cedros-button-warning' : 'cedros-button-primary'}`}\n onClick={(e) => {\n e.stopPropagation();\n handleProcessSingle(item);\n }}\n disabled={isProcessing || processingAll}\n title={\n withinPrivacyPeriod\n ? 'Early withdrawal (requires confirmation)'\n : 'Process this withdrawal'\n }\n >\n {isProcessing ? '...' : withinPrivacyPeriod ? 'Early' : 'Process'}\n </button>\n </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 privacy period deposits component\n *\n * Shows deposits that are still in the privacy period (completed but not yet ready for withdrawal).\n * Requires system admin privileges.\n */\n\nimport { useState, useEffect, useCallback } from 'react';\nimport { useAdminDeposits } from '../../../hooks/useAdminDeposits';\nimport type { AdminDepositItem, AdminDepositListResponse } from '../../../types/deposit';\nimport { FeatureDisabledMessage } from './FeatureDisabledMessage';\nimport { isFeatureDisabledError } from './featureDisabled';\n\nexport interface AdminPrivacyPeriodDepositsProps {\n /** Number of items per page (default: 20) */\n pageSize?: number;\n /** Auto-refresh interval in milliseconds (0 to disable) */\n refreshInterval?: number;\n /** Additional CSS classes */\n className?: string;\n /** Callback when list is loaded */\n onLoad?: (response: AdminDepositListResponse) => void;\n /** Callback when a deposit item is clicked */\n onItemClick?: (item: AdminDepositItem) => void;\n}\n\nfunction formatAmount(lamports: number | null): string {\n if (lamports === null || lamports === undefined) return '—';\n const solAmount = lamports / 1_000_000_000;\n return `${solAmount.toFixed(4)} SOL`;\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 hour: '2-digit',\n minute: '2-digit',\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 getTimeRemaining(dateString: string): string {\n const date = new Date(dateString);\n const now = new Date();\n const diffMs = date.getTime() - now.getTime();\n\n if (diffMs <= 0) return 'Ready';\n\n const diffMins = Math.floor(diffMs / 60000);\n const diffHours = Math.floor(diffMins / 60);\n const diffDays = Math.floor(diffHours / 24);\n\n if (diffDays > 0) {\n const remainingHours = diffHours % 24;\n return remainingHours > 0 ? `${diffDays}d ${remainingHours}h` : `${diffDays}d`;\n }\n if (diffHours > 0) {\n const remainingMins = diffMins % 60;\n return remainingMins > 0 ? `${diffHours}h ${remainingMins}m` : `${diffHours}h`;\n }\n return `${diffMins}m`;\n}\n\n/**\n * Admin privacy period deposits display\n *\n * Shows deposits that are still in the privacy period (not yet available for withdrawal).\n */\nexport function AdminPrivacyPeriodDeposits({\n pageSize = 20,\n refreshInterval = 0,\n className = '',\n onLoad,\n onItemClick,\n}: AdminPrivacyPeriodDepositsProps) {\n const { listInPrivacyPeriod, isLoading, error, clearError } = useAdminDeposits();\n\n const [items, setItems] = useState<AdminDepositItem[]>([]);\n const [total, setTotal] = useState(0);\n const [offset, setOffset] = useState(0);\n const [loadError, setLoadError] = useState<string | null>(null);\n\n const fetchItems = useCallback(async () => {\n try {\n const result = await listInPrivacyPeriod({ limit: pageSize, offset });\n setItems(result.deposits);\n setTotal(result.total);\n onLoad?.(result);\n setLoadError(null);\n } catch (err) {\n const message =\n err && typeof err === 'object' && 'message' in err\n ? String((err as { message: unknown }).message)\n : 'Failed to load deposits';\n setLoadError(message);\n }\n }, [pageSize, offset, listInPrivacyPeriod, 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 fetchItems();\n }, [fetchItems]);\n\n // Auto-refresh\n useEffect(() => {\n if (refreshInterval <= 0) return;\n\n const interval = setInterval(fetchItems, refreshInterval);\n return () => clearInterval(interval);\n }, [refreshInterval, fetchItems]);\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 // Feature disabled state\n const errorMessage = loadError || error;\n if (isFeatureDisabledError(errorMessage)) {\n return <FeatureDisabledMessage feature=\"Privacy Cash\" className={className} />;\n }\n\n // Error state\n if (errorMessage) {\n return (\n <div\n className={`cedros-admin-privacy-deposits cedros-admin-privacy-deposits-error ${className}`}\n >\n <p className=\"cedros-admin-error\">{errorMessage}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline\"\n onClick={() => {\n clearError();\n setLoadError(null);\n fetchItems();\n }}\n >\n Retry\n </button>\n </div>\n );\n }\n\n // Loading state (initial load only)\n if (isLoading && items.length === 0) {\n return (\n <div\n className={`cedros-admin-privacy-deposits cedros-admin-privacy-deposits-loading ${className}`}\n >\n <span className=\"cedros-admin-loading-indicator\" />\n <span className=\"cedros-admin-loading-text\">Loading deposits...</span>\n </div>\n );\n }\n\n return (\n <div className={`cedros-admin-privacy-deposits ${className}`}>\n <div className=\"cedros-admin-privacy-deposits-header\">\n <h4 className=\"cedros-admin-privacy-deposits-title\">In Privacy Period</h4>\n <div className=\"cedros-admin-privacy-deposits-actions\">\n <span className=\"cedros-admin-queue-count\">\n {total} deposit{total !== 1 ? 's' : ''}\n </span>\n <button\n type=\"button\"\n className=\"cedros-admin__stats-bar-refresh\"\n onClick={fetchItems}\n disabled={isLoading}\n title=\"Refresh list\"\n aria-label=\"Refresh list\"\n >\n {isLoading ? '...' : '↻'}\n </button>\n </div>\n </div>\n\n {items.length === 0 ? (\n <div className=\"cedros-admin-empty\">\n <p className=\"cedros-admin-empty-message\">No deposits in privacy period.</p>\n </div>\n ) : (\n <>\n <div className=\"cedros-admin-privacy-table\">\n <div className=\"cedros-admin-privacy-thead\">\n <div className=\"cedros-admin-privacy-th\">\n <button\n type=\"button\"\n className=\"cedros-admin-sort-button\"\n aria-label=\"Sort by user\"\n >\n User <span className=\"cedros-admin-sort-icon\">↕</span>\n </button>\n </div>\n <div className=\"cedros-admin-privacy-th\">\n <button\n type=\"button\"\n className=\"cedros-admin-sort-button\"\n aria-label=\"Sort by amount\"\n >\n Amount <span className=\"cedros-admin-sort-icon\">↕</span>\n </button>\n </div>\n <div className=\"cedros-admin-privacy-th\">\n <button\n type=\"button\"\n className=\"cedros-admin-sort-button\"\n aria-label=\"Sort by deposited\"\n >\n Deposited <span className=\"cedros-admin-sort-icon\">↕</span>\n </button>\n </div>\n <div className=\"cedros-admin-privacy-th\">\n <button\n type=\"button\"\n className=\"cedros-admin-sort-button\"\n aria-label=\"Sort by ready in\"\n >\n Ready In <span className=\"cedros-admin-sort-icon\">↕</span>\n </button>\n </div>\n </div>\n {items.map((item) => (\n <div\n key={item.id}\n className=\"cedros-admin-privacy-row\"\n onClick={() => onItemClick?.(item)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onItemClick?.(item);\n }\n }}\n role={onItemClick ? 'button' : undefined}\n tabIndex={onItemClick ? 0 : undefined}\n >\n <div className=\"cedros-admin-privacy-td\" title={item.userId}>\n {truncateId(item.userId)}\n </div>\n <div className=\"cedros-admin-privacy-td\">{formatAmount(item.amountLamports)}</div>\n <div className=\"cedros-admin-privacy-td\">\n {item.completedAt ? formatDate(item.completedAt) : '—'}\n </div>\n <div className=\"cedros-admin-privacy-td cedros-admin-privacy-remaining\">\n {item.withdrawalAvailableAt ? getTimeRemaining(item.withdrawalAvailableAt) : '—'}\n </div>\n </div>\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 withdrawal history component\n *\n * Shows deposits that have been fully withdrawn (processed).\n * Requires system admin privileges.\n */\n\nimport { useState, useEffect, useCallback, useMemo } from 'react';\nimport { useAdminDeposits } from '../../../hooks/useAdminDeposits';\nimport type { AdminDepositItem, AdminDepositListResponse } from '../../../types/deposit';\nimport { FeatureDisabledMessage } from './FeatureDisabledMessage';\nimport { isFeatureDisabledError } from './featureDisabled';\n\ntype WithdrawalSortField = 'userId' | 'amountLamports' | 'completedAt' | 'withdrawalTxSignature';\ntype SortOrder = 'asc' | 'desc';\n\nexport interface AdminWithdrawalHistoryProps {\n /** Number of items per page (default: 20) */\n pageSize?: number;\n /** Auto-refresh interval in milliseconds (0 to disable) */\n refreshInterval?: number;\n /** Additional CSS classes */\n className?: string;\n /** Callback when list is loaded */\n onLoad?: (response: AdminDepositListResponse) => void;\n /** Callback when a withdrawal item is clicked */\n onItemClick?: (item: AdminDepositItem) => void;\n}\n\nfunction formatAmount(lamports: number | null): string {\n if (lamports === null || lamports === undefined) return '—';\n const solAmount = lamports / 1_000_000_000;\n return `${solAmount.toFixed(4)} SOL`;\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 hour: '2-digit',\n minute: '2-digit',\n });\n}\n\nfunction truncateSignature(sig: string): string {\n if (sig.length <= 16) return sig;\n return `${sig.slice(0, 8)}...${sig.slice(-6)}`;\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\n/**\n * Admin withdrawal history display\n *\n * Shows deposits that have been fully withdrawn.\n */\nexport function AdminWithdrawalHistory({\n pageSize = 20,\n refreshInterval = 0,\n className = '',\n onLoad,\n onItemClick,\n}: AdminWithdrawalHistoryProps) {\n const { listDeposits, isLoading, error, clearError } = useAdminDeposits();\n\n const [items, setItems] = useState<AdminDepositItem[]>([]);\n const [total, setTotal] = useState(0);\n const [offset, setOffset] = useState(0);\n const [loadError, setLoadError] = useState<string | null>(null);\n const [sortField, setSortField] = useState<WithdrawalSortField>('completedAt');\n const [sortOrder, setSortOrder] = useState<SortOrder>('desc');\n\n const toggleSort = (field: WithdrawalSortField) => {\n if (sortField === field) {\n setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc');\n } else {\n setSortField(field);\n setSortOrder('desc');\n }\n };\n\n const sortedItems = useMemo(() => {\n return [...items].sort((a, b) => {\n let aVal: string | number;\n let bVal: string | number;\n\n switch (sortField) {\n case 'userId':\n aVal = a.userId.toLowerCase();\n bVal = b.userId.toLowerCase();\n break;\n case 'amountLamports':\n aVal = a.amountLamports ?? 0;\n bVal = b.amountLamports ?? 0;\n break;\n case 'completedAt':\n aVal = a.completedAt ? new Date(a.completedAt).getTime() : 0;\n bVal = b.completedAt ? new Date(b.completedAt).getTime() : 0;\n break;\n case 'withdrawalTxSignature':\n aVal = a.withdrawalTxSignature || '';\n bVal = b.withdrawalTxSignature || '';\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 }, [items, sortField, sortOrder]);\n\n const fetchItems = useCallback(async () => {\n try {\n const result = await listDeposits({ status: 'withdrawn', limit: pageSize, offset });\n setItems(result.deposits);\n setTotal(result.total);\n onLoad?.(result);\n setLoadError(null);\n } catch (err) {\n const message =\n err && typeof err === 'object' && 'message' in err\n ? String((err as { message: unknown }).message)\n : 'Failed to load withdrawal history';\n setLoadError(message);\n }\n }, [pageSize, offset, listDeposits, 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 fetchItems();\n }, [fetchItems]);\n\n // Auto-refresh\n useEffect(() => {\n if (refreshInterval <= 0) return;\n\n const interval = setInterval(fetchItems, refreshInterval);\n return () => clearInterval(interval);\n }, [refreshInterval, fetchItems]);\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 // Feature disabled state\n const errorMessage = loadError || error;\n if (isFeatureDisabledError(errorMessage)) {\n return <FeatureDisabledMessage feature=\"Privacy Cash\" className={className} />;\n }\n\n // Error state\n if (errorMessage) {\n return (\n <div\n className={`cedros-admin-withdrawal-history cedros-admin-withdrawal-history-error ${className}`}\n >\n <p className=\"cedros-admin-error\">{errorMessage}</p>\n <button\n type=\"button\"\n className=\"cedros-button cedros-button-outline\"\n onClick={() => {\n clearError();\n setLoadError(null);\n fetchItems();\n }}\n >\n Retry\n </button>\n </div>\n );\n }\n\n // Loading state (initial load only)\n if (isLoading && items.length === 0) {\n return (\n <div\n className={`cedros-admin-withdrawal-history cedros-admin-withdrawal-history-loading ${className}`}\n >\n <span className=\"cedros-admin-loading-indicator\" />\n <span className=\"cedros-admin-loading-text\">Loading withdrawal history...</span>\n </div>\n );\n }\n\n return (\n <div className={`cedros-admin-withdrawal-history ${className}`}>\n <div className=\"cedros-admin-withdrawal-history-header\">\n <h4 className=\"cedros-admin-withdrawal-history-title\">Withdrawal History</h4>\n <div className=\"cedros-admin-withdrawal-history-actions\">\n <span className=\"cedros-admin-queue-count\">\n {total} withdrawal{total !== 1 ? 's' : ''}\n </span>\n <button\n type=\"button\"\n className=\"cedros-admin__stats-bar-refresh\"\n onClick={fetchItems}\n disabled={isLoading}\n title=\"Refresh list\"\n aria-label=\"Refresh list\"\n >\n {isLoading ? '...' : '↻'}\n </button>\n </div>\n </div>\n\n {items.length === 0 ? (\n <div className=\"cedros-admin-empty\">\n <p className=\"cedros-admin-empty-message\">No withdrawals processed yet.</p>\n </div>\n ) : (\n <>\n <div className=\"cedros-admin-history-table\">\n <div className=\"cedros-admin-history-thead\">\n <div className=\"cedros-admin-history-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'userId' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('userId')}\n aria-label=\"Sort by user\"\n >\n User{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'userId' ? (sortOrder === 'asc' ? '↑' : '↓') : '↕'}\n </span>\n </button>\n </div>\n <div className=\"cedros-admin-history-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'amountLamports' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('amountLamports')}\n aria-label=\"Sort by amount\"\n >\n Amount{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'amountLamports' ? (sortOrder === 'asc' ? '↑' : '↓') : '↕'}\n </span>\n </button>\n </div>\n <div className=\"cedros-admin-history-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'completedAt' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('completedAt')}\n aria-label=\"Sort by processed\"\n >\n Processed{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'completedAt' ? (sortOrder === 'asc' ? '↑' : '↓') : '↕'}\n </span>\n </button>\n </div>\n <div className=\"cedros-admin-history-th\">\n <button\n type=\"button\"\n className={`cedros-admin-sort-button ${sortField === 'withdrawalTxSignature' ? 'cedros-admin-sort-active' : ''}`}\n onClick={() => toggleSort('withdrawalTxSignature')}\n aria-label=\"Sort by transaction\"\n >\n Transaction{' '}\n <span className=\"cedros-admin-sort-icon\">\n {sortField === 'withdrawalTxSignature'\n ? sortOrder === 'asc'\n ? '↑'\n : '↓'\n : '↕'}\n </span>\n </button>\n </div>\n </div>\n {sortedItems.map((item) => (\n <div\n key={item.id}\n className=\"cedros-admin-history-row\"\n onClick={() => onItemClick?.(item)}\n onKeyDown={(e) => {\n if (e.key === 'Enter' || e.key === ' ') {\n e.preventDefault();\n onItemClick?.(item);\n }\n }}\n role={onItemClick ? 'button' : undefined}\n tabIndex={onItemClick ? 0 : undefined}\n >\n <div className=\"cedros-admin-history-td\" title={item.userId}>\n {truncateId(item.userId)}\n </div>\n <div className=\"cedros-admin-history-td\">{formatAmount(item.amountLamports)}</div>\n <div className=\"cedros-admin-history-td\">\n {item.completedAt ? formatDate(item.completedAt) : '—'}\n </div>\n <div className=\"cedros-admin-history-td\">\n {item.withdrawalTxSignature ? (\n <a\n href={`https://orbmarkets.io/tx/${item.withdrawalTxSignature}`}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"cedros-admin-tx-link\"\n onClick={(e) => e.stopPropagation()}\n title={item.withdrawalTxSignature}\n >\n {truncateSignature(item.withdrawalTxSignature)}\n </a>\n ) : (\n '—'\n )}\n </div>\n </div>\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"],"names":["AdminWithdrawalStats","refreshInterval","className","onLoad","getStats","isLoading","error","clearError","useAdminDeposits","stats","setStats","useState","loadError","setLoadError","fetchStats","useCallback","result","err","message","useEffect","interval","errorMessage","jsxs","jsx","StatsBar","formatAmount","lamports","formatDate","dateString","truncateId","id","getTimeElapsed","date","diffMs","diffMins","diffHours","diffDays","isWithinPrivacyPeriod","withdrawalAvailableAt","AdminWithdrawalQueue","pageSize","onItemClick","onWithdrawalProcessed","onAllProcessed","listPendingWithdrawals","processWithdrawal","processAllWithdrawals","items","setItems","total","setTotal","offset","setOffset","sortField","setSortField","sortOrder","setSortOrder","toggleSort","field","sortedItems","useMemo","b","aVal","bVal","processingId","setProcessingId","processingAll","setProcessingAll","processResult","setProcessResult","earlyWithdrawalItem","setEarlyWithdrawalItem","fetchItems","timer","totalPages","currentPage","goToPage","page","newOffset","handleProcessSingle","item","force","handleProcessAll","e","Fragment","withinPrivacyPeriod","isProcessing","getTimeRemaining","now","remainingHours","remainingMins","AdminPrivacyPeriodDeposits","listInPrivacyPeriod","truncateSignature","sig","AdminWithdrawalHistory","listDeposits","a"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const e=require("react/jsx-runtime"),o=require("react"),A=require("./LoadingSpinner-d6sSxgQN.cjs"),E=require("./ErrorMessage-CHbYbVi2.cjs"),C=require("./AutosaveStatus-CYkC2aI_.cjs"),D=require("./apiClient-CTTKhsYb.cjs"),$=require("./useOrgs-CVbacmaQ.cjs");function T(){const{config:n,_internal:g}=D.useCedrosLogin(),u=n.serverUrl,f=o.useRef(g?.getAccessToken??(()=>null));f.current=g?.getAccessToken??(()=>null);const[b,S]=o.useState([]),[v,x]=o.useState(0),[k,c]=o.useState(!1),[N,r]=o.useState(null),h=o.useCallback(()=>{const d=f.current();return{"Content-Type":"application/json",...d?{Authorization:`Bearer ${d}`}:{}}},[]),p=o.useCallback(async(d,t=50,a=0)=>{c(!0),r(null);try{const i=new URLSearchParams;d&&i.set("org_id",d),i.set("limit",String(t)),i.set("offset",String(a));const s=await fetch(`${u}/admin/sso-providers?${i}`,{headers:h()});if(!s.ok){const P=await s.json().catch(()=>({}));throw new Error(P.error||`Failed to fetch SSO providers: ${s.status}`)}const j=await s.json();return S(j.providers),x(j.total),j}catch(i){const s=i instanceof Error?i:new Error(String(i));throw r(s),s}finally{c(!1)}},[u,h]),l=o.useCallback(async d=>{c(!0),r(null);try{const t=await fetch(`${u}/admin/sso-providers`,{method:"POST",headers:h(),body:JSON.stringify(d)});if(!t.ok){const i=await t.json().catch(()=>({}));throw new Error(i.error||`Failed to create SSO provider: ${t.status}`)}const a=await t.json();return S(i=>[...i,a]),x(i=>i+1),a}catch(t){const a=t instanceof Error?t:new Error(String(t));throw r(a),a}finally{c(!1)}},[u,h]),m=o.useCallback(async(d,t)=>{c(!0),r(null);try{const a=await fetch(`${u}/admin/sso-providers/${d}`,{method:"PUT",headers:h(),body:JSON.stringify(t)});if(!a.ok){const s=await a.json().catch(()=>({}));throw new Error(s.error||`Failed to update SSO provider: ${a.status}`)}const i=await a.json();return S(s=>s.map(j=>j.id===d?i:j)),i}catch(a){const i=a instanceof Error?a:new Error(String(a));throw r(i),i}finally{c(!1)}},[u,h]),w=o.useCallback(async d=>{c(!0),r(null);try{const t=await fetch(`${u}/admin/sso-providers/${d}`,{method:"DELETE",headers:h()});if(!t.ok){const a=await t.json().catch(()=>({}));throw new Error(a.error||`Failed to delete SSO provider: ${t.status}`)}S(a=>a.filter(i=>i.id!==d)),x(a=>a-1)}catch(t){const a=t instanceof Error?t:new Error(String(t));throw r(a),a}finally{c(!1)}},[u,h]),y=o.useCallback(async(d,t)=>m(d,{enabled:t}),[m]);return{providers:b,total:v,isLoading:k,error:N,fetchProviders:p,createProvider:l,updateProvider:m,deleteProvider:w,toggleProvider:y}}function I({className:n}){const{providers:g,isLoading:u,error:f,fetchProviders:b,createProvider:S,updateProvider:v,deleteProvider:x,toggleProvider:k}=T(),{activeOrg:c}=$.useOrgs(),[N,r]=o.useState("list"),[h,p]=o.useState(null),[l,m]=o.useState(null);o.useEffect(()=>{b(c?.id)},[b,c?.id]);const w=()=>{p(null),m(null),r("add")},y=s=>{p(s),m(null),r("edit")},d=()=>{r("list"),p(null),m(null)},t=async s=>{if(confirm(`Delete SSO provider "${s.name}"? This cannot be undone.`))try{await x(s.id)}catch{}},a=async s=>{try{await k(s.id,!s.enabled)}catch{}},i=async s=>{m(null);try{N==="add"?await S(s):h&&await v(h.id,s),r("list"),p(null)}catch(j){m(j instanceof Error?j.message:"Failed to save provider")}};return u&&g.length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${n??""}`,children:[e.jsx(A.LoadingSpinner,{}),e.jsx("span",{children:"Loading SSO providers..."})]}):N==="add"||N==="edit"?e.jsx("div",{className:`cedros-system-settings ${n??""}`,children:e.jsx(F,{provider:h,orgId:c?.id,error:l,isLoading:u,onSave:i,onCancel:d})}):e.jsxs("div",{className:`cedros-system-settings ${n??""}`,children:[e.jsxs("div",{className:"cedros-settings-page-header",children:[e.jsxs("div",{className:"cedros-settings-page-header-content",children:[e.jsx("h2",{className:"cedros-settings-page-title",children:"SSO Providers"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Configure OIDC identity providers for enterprise single sign-on."})]}),e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-primary",onClick:w,children:"Add Provider"})]}),f&&e.jsx(E.ErrorMessage,{error:f.message}),g.length===0?e.jsxs("div",{className:"cedros-system-settings-empty",children:[e.jsx("p",{children:"No SSO providers configured."}),e.jsx("p",{className:"cedros-text-muted",children:"Add an OIDC provider like Okta, Azure AD, or Auth0 to enable enterprise SSO."})]}):e.jsx("div",{className:"cedros-sso-provider-list",children:g.map(s=>e.jsx(L,{provider:s,onEdit:()=>y(s),onDelete:()=>t(s),onToggle:()=>a(s)},s.id))})]})}function L({provider:n,onEdit:g,onDelete:u,onToggle:f}){return e.jsxs("div",{className:`cedros-sso-provider-card ${n.enabled?"":"cedros-sso-provider-card--disabled"}`,children:[e.jsxs("div",{className:"cedros-sso-provider-card-header",children:[e.jsxs("div",{className:"cedros-sso-provider-card-info",children:[e.jsx("h3",{className:"cedros-sso-provider-card-name",children:n.name}),e.jsx("p",{className:"cedros-sso-provider-card-issuer",children:n.issuerUrl})]}),e.jsxs("button",{type:"button",role:"switch","aria-checked":n.enabled,className:`cedros-toggle ${n.enabled?"cedros-toggle-on":"cedros-toggle-off"}`,onClick:f,children:[e.jsx("span",{className:"cedros-toggle-track",children:e.jsx("span",{className:"cedros-toggle-thumb"})}),e.jsx("span",{className:"cedros-toggle-label",children:n.enabled?"Enabled":"Disabled"})]})]}),e.jsxs("div",{className:"cedros-sso-provider-card-details",children:[e.jsxs("div",{className:"cedros-sso-provider-card-detail",children:[e.jsx("span",{className:"cedros-sso-provider-card-detail-label",children:"Client ID"}),e.jsx("code",{className:"cedros-sso-provider-card-detail-value",children:n.clientId})]}),n.emailDomain&&e.jsxs("div",{className:"cedros-sso-provider-card-detail",children:[e.jsx("span",{className:"cedros-sso-provider-card-detail-label",children:"Email Domain"}),e.jsxs("span",{className:"cedros-sso-provider-card-detail-value",children:["@",n.emailDomain]})]}),e.jsxs("div",{className:"cedros-sso-provider-card-detail",children:[e.jsx("span",{className:"cedros-sso-provider-card-detail-label",children:"Registration"}),e.jsx("span",{className:"cedros-sso-provider-card-detail-value",children:n.allowRegistration?"Allowed":"Existing users only"})]})]}),e.jsxs("div",{className:"cedros-sso-provider-card-actions",children:[e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-ghost",onClick:g,children:"Edit"}),e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-ghost cedros-btn-danger",onClick:u,children:"Delete"})]})]})}function F({provider:n,orgId:g,error:u,isLoading:f,onSave:b,onCancel:S}){const v=!!n,[x,k]=o.useState(n?.name??""),[c,N]=o.useState(n?.issuerUrl??""),[r,h]=o.useState(n?.clientId??""),[p,l]=o.useState(""),[m,w]=o.useState(n?.emailDomain??""),[y,d]=o.useState(n?.allowRegistration??!0),[t,a]=o.useState(n?.enabled??!0),i=o.useCallback(s=>{if(s.preventDefault(),v){const j={name:x,issuerUrl:c,clientId:r,emailDomain:m||null,allowRegistration:y,enabled:t};p&&(j.clientSecret=p),b(j)}else{if(!g)return;b({orgId:g,name:x,issuerUrl:c,clientId:r,clientSecret:p,emailDomain:m||null,allowRegistration:y,enabled:t})}},[v,g,x,c,r,p,m,y,t,b]);return e.jsxs("form",{className:"cedros-sso-provider-form",onSubmit:i,children:[e.jsx("div",{className:"cedros-settings-page-header",children:e.jsxs("div",{className:"cedros-settings-page-header-content",children:[e.jsx("h2",{className:"cedros-settings-page-title",children:v?"Edit SSO Provider":"Add SSO Provider"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Configure an OIDC identity provider for enterprise single sign-on."})]})}),u&&e.jsx(E.ErrorMessage,{error:u}),e.jsxs("div",{className:"cedros-form-section",children:[e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-name",children:"Provider Name"}),e.jsx("input",{id:"sso-name",type:"text",className:"cedros-form-input",value:x,onChange:s=>k(s.target.value),placeholder:"e.g., Okta, Azure AD",required:!0})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-issuer",children:"Issuer URL"}),e.jsx("input",{id:"sso-issuer",type:"url",className:"cedros-form-input",value:c,onChange:s=>N(s.target.value),placeholder:"https://your-org.okta.com",required:!0}),e.jsx("p",{className:"cedros-form-hint",children:"The OIDC issuer URL. Must support discovery at /.well-known/openid-configuration"})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-client-id",children:"Client ID"}),e.jsx("input",{id:"sso-client-id",type:"text",className:"cedros-form-input",value:r,onChange:s=>h(s.target.value),placeholder:"OAuth client ID",required:!0})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsxs("label",{className:"cedros-form-label",htmlFor:"sso-client-secret",children:["Client Secret"," ",v&&e.jsx("span",{className:"cedros-form-hint-inline",children:"(leave blank to keep current)"})]}),e.jsx("input",{id:"sso-client-secret",type:"password",className:"cedros-form-input",value:p,onChange:s=>l(s.target.value),placeholder:v?"••••••••":"OAuth client secret",required:!v})]}),e.jsxs("div",{className:"cedros-form-group",children:[e.jsx("label",{className:"cedros-form-label",htmlFor:"sso-email-domain",children:"Email Domain (optional)"}),e.jsx("input",{id:"sso-email-domain",type:"text",className:"cedros-form-input",value:m,onChange:s=>w(s.target.value),placeholder:"company.com"}),e.jsx("p",{className:"cedros-form-hint",children:"Restrict to users with emails from this domain"})]}),e.jsx("div",{className:"cedros-form-group",children:e.jsxs("label",{className:"cedros-form-checkbox",children:[e.jsx("input",{type:"checkbox",checked:y,onChange:s=>d(s.target.checked)}),e.jsx("span",{children:"Allow new user registration via SSO"})]})}),e.jsx("div",{className:"cedros-form-group",children:e.jsxs("label",{className:"cedros-form-checkbox",children:[e.jsx("input",{type:"checkbox",checked:t,onChange:s=>a(s.target.checked)}),e.jsx("span",{children:"Enable this provider"})]})})]}),e.jsxs("div",{className:"cedros-form-actions",children:[e.jsx("button",{type:"button",className:"cedros-btn cedros-btn-ghost",onClick:S,disabled:f,children:"Cancel"}),e.jsx("button",{type:"submit",className:"cedros-btn cedros-btn-primary",disabled:f,children:f?"Saving...":v?"Save Changes":"Add Provider"})]})]})}const O=[{id:"email",label:"Email",categories:["auth.email"]},{id:"google",label:"Google",categories:["auth.google"]},{id:"apple",label:"Apple",categories:["auth.apple"]},{id:"solana",label:"Solana",categories:["auth.solana"]},{id:"passkeys",label:"Passkeys",categories:["auth.webauthn"]},{id:"instantlink",label:"Instant Link",categories:["auth.instantlink"]},{id:"sso",label:"SSO Providers",categories:[],isCustom:!0}];function R({className:n}){const{settings:g,edits:u,isLoading:f,autosaveStatus:b,autosaveError:S,error:v,fetchSettings:x,handleChange:k}=C.useSettingsAutosave(),[c,N]=o.useState("email");o.useEffect(()=>{x()},[x]);const r=O.find(l=>l.id===c),h=o.useMemo(()=>{if(!r)return[];const l=[];for(const m of r.categories){const w=g[m]??[];l.push(...w)}return l},[g,r]),p=o.useMemo(()=>r?.keys?h.filter(l=>r.keys.includes(l.key)).sort((l,m)=>r.keys.indexOf(l.key)-r.keys.indexOf(m.key)):h,[h,r]);return f&&Object.keys(g).length===0?e.jsxs("div",{className:`cedros-system-settings cedros-system-settings-loading ${n??""}`,children:[e.jsx(A.LoadingSpinner,{}),e.jsx("span",{children:"Loading settings..."})]}):v?e.jsx("div",{className:`cedros-system-settings ${n??""}`,children:e.jsx(E.ErrorMessage,{error:v.message})}):e.jsxs("div",{className:`cedros-system-settings ${n??""}`,children:[e.jsxs("div",{className:"cedros-settings-page-header",children:[e.jsxs("div",{className:"cedros-settings-page-header-content",children:[e.jsx("h2",{className:"cedros-settings-page-title",children:"Authentication"}),e.jsx("p",{className:"cedros-settings-page-description",children:"Configure authentication providers and methods for user sign-in."})]}),e.jsx(C.AutosaveStatus,{status:b,error:S})]}),e.jsx("div",{className:"cedros-admin-tabs cedros-admin-tabs--line",children:O.map(l=>e.jsx("button",{type:"button",className:`cedros-admin-tab ${c===l.id?"cedros-admin-tab-active":""}`,onClick:()=>N(l.id),"aria-selected":c===l.id,role:"tab",children:l.label},l.id))}),e.jsx("div",{className:"cedros-admin-tab-content",role:"tabpanel",children:r?.isCustom?e.jsx(I,{}):p.length===0?e.jsx("div",{className:"cedros-system-settings-empty",children:e.jsxs("p",{children:["No settings found for ",r?.label??"this provider","."]})}):e.jsx(C.SettingsSection,{settings:p,edits:u,onChange:k})})]})}exports.AuthenticationSettings=R;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";const u=require("react"),N=require("./useSystemSettings-D9Cr7ZTl.cjs"),e=require("react/jsx-runtime"),P=800,C=2e3;function L(){const{settings:t,isLoading:s,error:a,fetchSettings:n,updateSettings:l}=N.useSystemSettings(),[i,p]=u.useState({}),[r,o]=u.useState("idle"),[c,d]=u.useState(null),_=u.useRef(null),h=u.useRef(null),g=u.useRef({});u.useEffect(()=>()=>{_.current&&clearTimeout(_.current),h.current&&clearTimeout(h.current)},[]);const k=u.useCallback(async()=>{const b={...g.current};if(Object.keys(b).length===0){o("idle");return}o("saving"),d(null);const y=Object.entries(b).map(([m,v])=>({key:m,value:v}));try{await l(y),p(m=>{const v={...m};for(const j of Object.keys(b))delete v[j];return v});for(const m of Object.keys(b))delete g.current[m];o("saved"),h.current&&clearTimeout(h.current),h.current=setTimeout(()=>{o("idle")},C)}catch(m){o("error"),d(m instanceof Error?m.message:"Failed to save")}},[l]),S=u.useCallback((b,y)=>{p(m=>({...m,[b]:y})),g.current[b]=y,d(null),o("pending"),_.current&&clearTimeout(_.current),_.current=setTimeout(()=>{k()},P)},[k]),T=u.useCallback(b=>{if(i[b]!==void 0)return i[b];for(const y of Object.values(t)){const m=y.find(v=>v.key===b);if(m)return m.value}return""},[i,t]);return{settings:t,edits:i,isLoading:s,autosaveStatus:r,autosaveError:c,error:a,fetchSettings:n,handleChange:S,getEffectiveValue:T}}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 A(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 O={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.",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.",inputType:"text"},auth_google_client_secret:{key:"auth_google_client_secret",label:"Google Client Secret",description:"OAuth 2.0 client secret from Google Cloud Console.",inputType:"secret"},auth_apple_enabled:{key:"auth_apple_enabled",label:"Enable Sign in with Apple",description:"Allow users to authenticate with their Apple ID.",inputType:"boolean"},auth_apple_client_id:{key:"auth_apple_client_id",label:"Apple Services ID",description:"The Services ID configured in your Apple Developer account.",inputType:"text"},auth_apple_team_id:{key:"auth_apple_team_id",label:"Apple Team ID",description:"Your Apple Developer Team ID.",inputType:"text"},auth_apple_key_id:{key:"auth_apple_key_id",label:"Apple Key ID",description:"The Key ID for your Sign in with Apple private key.",inputType:"text"},auth_apple_private_key:{key:"auth_apple_private_key",label:"Apple Private Key",description:"The private key file contents (PEM format) for Sign in with Apple.",inputType:"secret",multiline:!0},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:"Allow passwordless login via magic link sent to email.",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.",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:"How users can recover their wallet if they lose access.",inputType:"select",presets:[{label:"Share C Only (Recommended)",value:"share_c_only"},{label:"Full Seed Phrase",value:"full_seed"},{label:"No Recovery",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 withdraw SOL/SPL tokens from their embedded wallet to external addresses.",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 your email service provider for automatic configuration.",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 (e.g., smtp.sendgrid.net).",inputType:"text"},email_smtp_port:{key:"email_smtp_port",label:"SMTP Port",description:"SMTP server port. Common: 587 (TLS), 465 (SSL), 25 (unencrypted).",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.",inputType:"text"},email_smtp_password:{key:"email_smtp_password",label:"API Key",description:"API key or password for your email provider.",inputType:"secret"},email_smtp_tls:{key:"email_smtp_tls",label:"Use TLS",description:"Enable TLS encryption for SMTP connections.",inputType:"boolean"},email_from_address:{key:"email_from_address",label:"From Address",description:"Default sender email address (e.g., noreply@example.com).",inputType:"text"},email_from_name:{key:"email_from_name",label:"From Name",description:'Default sender display name (e.g., "My App").',inputType:"text"},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"},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."}}},x=["SOL","USDC","USDT","EURC","USD1","PYUSD","USDH","CASH","BONK","ORE"];function f(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 E({settings:t,edits:s,onChange:a,externalWarnings:n}){return e.jsx("div",{className:"cedros-settings-grid",children:t.map(l=>e.jsx(U,{setting:l,editValue:s[l.key],onChange:a,externalWarning:n?.[l.key]},l.key))})}function U({setting:t,editValue:s,onChange:a,externalWarning:n}){const l=O[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:d,below:_,message:h}=l.warningThreshold;return d!==void 0&&c>d||_!==void 0&&c<_?h: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(w,{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:f(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:f(l.description)})]}),e.jsxs("div",{className:"cedros-setting-control",children:[e.jsx(w,{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 w({meta:t,value:s,onChange:a}){switch(t.inputType){case"duration":return e.jsx(I,{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(R,{value:s,onChange:a,presets:t.presets??[],unit:t.unit});case"number":return e.jsx(F,{value:s,onChange:a,min:t.min,max:t.max,unit:t.unit});case"tokenList":return e.jsx(W,{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"tokenSymbolList":return e.jsx(H,{value:s,onChange:a});default:return e.jsx("input",{type:"text",value:s,onChange:n=>a(n.target.value),className:"cedros-setting-input"})}}function I({value:t,onChange:s,presets:a,min:n=0}){const l=parseInt(t,10)||0,i=A(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 R({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 F({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)},[]),d=u.useCallback(_=>{s(_.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:d,className:"cedros-setting-input cedros-setting-textarea",placeholder:"Enter secret value...",rows:4}):e.jsx("input",{type:i?"text":"password",value:t,onChange:d,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 W({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 d=[...a];d[r]={...d[r],[o]:c},n(d)},[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:x.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 H({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:x.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..."})]})}function B({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=B;exports.SettingsSection=E;exports.useSettingsAutosave=L;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"AutosaveStatus-CYkC2aI_.cjs","sources":["../src/hooks/useSettingsAutosave.ts","../src/components/admin/settings/settingsMetadata.ts","../src/components/admin/settings/settingsInputs.tsx","../src/components/admin/settings/AutosaveStatus.tsx"],"sourcesContent":["import { useState, useCallback, useEffect, useRef } from 'react';\nimport type { UpdateSettingRequest } from '../types';\nimport { useSystemSettings } from './useSystemSettings';\n\n/** Autosave status */\nexport type AutosaveStatus = 'idle' | 'pending' | 'saving' | 'saved' | 'error';\n\n/** Debounce delay in milliseconds */\nconst DEBOUNCE_MS = 800;\n\n/** How long to show \"saved\" status before returning to idle */\nconst SAVED_DISPLAY_MS = 2000;\n\nexport interface UseSettingsAutosaveReturn {\n /** Settings grouped by category */\n settings: Record<string, import('../types').SystemSetting[]>;\n /** Current edits (key -> value) */\n edits: Record<string, string>;\n /** Whether initial load is in progress */\n isLoading: boolean;\n /** Current autosave status */\n autosaveStatus: AutosaveStatus;\n /** Error message if autosave failed */\n autosaveError: string | null;\n /** Loading error */\n error: Error | null;\n /** Fetch settings from server */\n fetchSettings: () => Promise<void>;\n /** Handle a setting change (triggers autosave) */\n handleChange: (key: string, value: string) => void;\n /** Get effective value (edit or original) */\n getEffectiveValue: (key: string) => string;\n}\n\n/**\n * Hook for managing system settings with autosave.\n *\n * Automatically saves changes after a debounce period.\n * Provides status feedback for the autosave process.\n */\nexport function useSettingsAutosave(): UseSettingsAutosaveReturn {\n const { settings, isLoading, error, fetchSettings, updateSettings } = useSystemSettings();\n\n const [edits, setEdits] = useState<Record<string, string>>({});\n const [autosaveStatus, setAutosaveStatus] = useState<AutosaveStatus>('idle');\n const [autosaveError, setAutosaveError] = useState<string | null>(null);\n\n // Refs for debounce timer and pending edits\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const savedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const pendingEditsRef = useRef<Record<string, string>>({});\n\n // Cleanup timers on unmount\n useEffect(() => {\n return () => {\n if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);\n if (savedTimerRef.current) clearTimeout(savedTimerRef.current);\n };\n }, []);\n\n // Perform the actual save\n const performSave = useCallback(async () => {\n const editsToSave = { ...pendingEditsRef.current };\n if (Object.keys(editsToSave).length === 0) {\n setAutosaveStatus('idle');\n return;\n }\n\n setAutosaveStatus('saving');\n setAutosaveError(null);\n\n const updates: UpdateSettingRequest[] = Object.entries(editsToSave).map(([key, value]) => ({\n key,\n value,\n }));\n\n try {\n await updateSettings(updates);\n\n // Clear saved edits from state\n setEdits((prev) => {\n const next = { ...prev };\n for (const key of Object.keys(editsToSave)) {\n delete next[key];\n }\n return next;\n });\n\n // Clear from pending ref\n for (const key of Object.keys(editsToSave)) {\n delete pendingEditsRef.current[key];\n }\n\n setAutosaveStatus('saved');\n\n // Reset to idle after delay\n if (savedTimerRef.current) clearTimeout(savedTimerRef.current);\n savedTimerRef.current = setTimeout(() => {\n setAutosaveStatus('idle');\n }, SAVED_DISPLAY_MS);\n } catch (err) {\n setAutosaveStatus('error');\n setAutosaveError(err instanceof Error ? err.message : 'Failed to save');\n }\n }, [updateSettings]);\n\n // Handle a setting change\n const handleChange = useCallback(\n (key: string, value: string) => {\n // Update local edits\n setEdits((prev) => ({ ...prev, [key]: value }));\n pendingEditsRef.current[key] = value;\n\n // Clear any error state\n setAutosaveError(null);\n\n // Set status to pending\n setAutosaveStatus('pending');\n\n // Reset debounce timer\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current);\n }\n\n debounceTimerRef.current = setTimeout(() => {\n performSave();\n }, DEBOUNCE_MS);\n },\n [performSave]\n );\n\n // Get effective value (edit or original)\n const getEffectiveValue = useCallback(\n (key: string) => {\n if (edits[key] !== undefined) return edits[key];\n for (const categorySettings of Object.values(settings)) {\n const found = categorySettings.find((s) => s.key === key);\n if (found) return found.value;\n }\n return '';\n },\n [edits, settings]\n );\n\n return {\n settings,\n edits,\n isLoading,\n autosaveStatus,\n autosaveError,\n error,\n fetchSettings,\n handleChange,\n getEffectiveValue,\n };\n}\n","/**\n * Settings metadata - rich descriptions and input configuration\n */\nimport type { SettingMeta } from '../../../types';\n\n// =============================================================================\n// DURATION UTILITIES\n// =============================================================================\n\nexport interface DurationParts {\n days: number;\n hours: number;\n minutes: number;\n seconds: number;\n}\n\nexport function secondsToDuration(totalSeconds: number): DurationParts {\n const days = Math.floor(totalSeconds / 86400);\n const hours = Math.floor((totalSeconds % 86400) / 3600);\n const minutes = Math.floor((totalSeconds % 3600) / 60);\n const seconds = totalSeconds % 60;\n return { days, hours, minutes, seconds };\n}\n\nexport function formatDuration(totalSeconds: number): string {\n const { days, hours, minutes } = secondsToDuration(totalSeconds);\n const parts: string[] = [];\n if (days > 0) parts.push(`${days}d`);\n if (hours > 0) parts.push(`${hours}h`);\n if (minutes > 0) parts.push(`${minutes}m`);\n if (parts.length === 0) parts.push(`${totalSeconds}s`);\n return parts.join(' ');\n}\n\n// =============================================================================\n// SETTING METADATA - Rich descriptions and input configuration\n// =============================================================================\n\nexport const SETTING_METADATA: Record<string, SettingMeta> = {\n // ============= Authentication Providers =============\n // Email auth\n auth_email_enabled: {\n key: 'auth_email_enabled',\n label: 'Enable Email Authentication',\n description: 'Allow users to sign up and log in with email/password.',\n inputType: 'boolean',\n },\n auth_email_require_verification: {\n key: 'auth_email_require_verification',\n label: 'Require Email Verification',\n description: 'Users must verify their email address before they can log in.',\n inputType: 'boolean',\n },\n auth_email_block_disposable: {\n key: 'auth_email_block_disposable',\n label: 'Block Disposable Emails',\n description: 'Reject registrations from known disposable email providers.',\n inputType: 'boolean',\n },\n\n // Google OAuth\n auth_google_enabled: {\n key: 'auth_google_enabled',\n label: 'Enable Google Sign-In',\n description: 'Allow users to authenticate with their Google account.',\n inputType: 'boolean',\n },\n auth_google_client_id: {\n key: 'auth_google_client_id',\n label: 'Google Client ID',\n description: 'OAuth 2.0 client ID from Google Cloud Console.',\n inputType: 'text',\n },\n auth_google_client_secret: {\n key: 'auth_google_client_secret',\n label: 'Google Client Secret',\n description: 'OAuth 2.0 client secret from Google Cloud Console.',\n inputType: 'secret',\n },\n\n // Apple OAuth\n auth_apple_enabled: {\n key: 'auth_apple_enabled',\n label: 'Enable Sign in with Apple',\n description: 'Allow users to authenticate with their Apple ID.',\n inputType: 'boolean',\n },\n auth_apple_client_id: {\n key: 'auth_apple_client_id',\n label: 'Apple Services ID',\n description: 'The Services ID configured in your Apple Developer account.',\n inputType: 'text',\n },\n auth_apple_team_id: {\n key: 'auth_apple_team_id',\n label: 'Apple Team ID',\n description: 'Your Apple Developer Team ID.',\n inputType: 'text',\n },\n auth_apple_key_id: {\n key: 'auth_apple_key_id',\n label: 'Apple Key ID',\n description: 'The Key ID for your Sign in with Apple private key.',\n inputType: 'text',\n },\n auth_apple_private_key: {\n key: 'auth_apple_private_key',\n label: 'Apple Private Key',\n description: 'The private key file contents (PEM format) for Sign in with Apple.',\n inputType: 'secret',\n multiline: true,\n },\n\n // Solana auth\n auth_solana_enabled: {\n key: 'auth_solana_enabled',\n label: 'Enable Solana Wallet Auth',\n description: 'Allow users to authenticate by signing with their Solana wallet.',\n inputType: 'boolean',\n },\n auth_solana_challenge_expiry: {\n key: 'auth_solana_challenge_expiry',\n label: 'Challenge Expiry',\n description: 'How long a wallet signature challenge is valid.',\n inputType: 'duration',\n min: 60,\n presets: [\n { label: '1 minute', value: '60' },\n { label: '5 minutes', value: '300' },\n { label: '10 minutes', value: '600' },\n ],\n },\n\n // WebAuthn/Passkeys\n auth_webauthn_enabled: {\n key: 'auth_webauthn_enabled',\n label: 'Enable WebAuthn/Passkeys',\n description: 'Allow passwordless authentication with FIDO2/WebAuthn credentials.',\n inputType: 'boolean',\n },\n auth_webauthn_rp_id: {\n key: 'auth_webauthn_rp_id',\n label: 'Relying Party ID',\n description: 'Usually your domain (e.g., example.com). Passkeys are bound to this.',\n inputType: 'text',\n },\n auth_webauthn_rp_name: {\n key: 'auth_webauthn_rp_name',\n label: 'Relying Party Name',\n description: 'Display name shown to users during passkey registration.',\n inputType: 'text',\n },\n auth_webauthn_rp_origin: {\n key: 'auth_webauthn_rp_origin',\n label: 'Allowed Origins',\n description: 'Comma-separated origins allowed for WebAuthn (e.g., https://example.com).',\n inputType: 'text',\n },\n\n // Instant Link (Magic Link)\n auth_instantlink_enabled: {\n key: 'auth_instantlink_enabled',\n label: 'Enable Instant Link',\n description: 'Allow passwordless login via magic link sent to email.',\n inputType: 'boolean',\n },\n auth_instantlink_expiry: {\n key: 'auth_instantlink_expiry',\n label: 'Link Expiry',\n description: 'How long the magic link remains valid.',\n inputType: 'duration',\n min: 60,\n presets: [\n { label: '5 minutes', value: '300' },\n { label: '15 minutes', value: '900' },\n { label: '30 minutes', value: '1800' },\n { label: '1 hour', value: '3600' },\n ],\n },\n auth_instantlink_rate_limit: {\n key: 'auth_instantlink_rate_limit',\n label: 'Rate Limit',\n description: 'Maximum instant link requests per email per hour.',\n inputType: 'select',\n presets: [\n { label: '3 per hour', value: '3' },\n { label: '5 per hour', value: '5' },\n { label: '10 per hour', value: '10' },\n ],\n },\n\n // ============= Feature Flags =============\n // Order: organizations, enterprise SSO, 2fa, embedded wallets, credit system\n feature_organizations: {\n key: 'feature_organizations',\n label: 'Organizations',\n description: 'Enable multi-user organizations with role-based access.',\n inputType: 'boolean',\n },\n feature_sso: {\n key: 'feature_sso',\n label: 'Enterprise SSO',\n description: 'Enable SAML/OIDC single sign-on for enterprise customers.',\n inputType: 'boolean',\n },\n feature_mfa: {\n key: 'feature_mfa',\n label: 'Two-Factor Authentication',\n description: 'Allow users to enable TOTP-based two-factor authentication.',\n inputType: 'boolean',\n },\n feature_wallet_signing: {\n key: 'feature_wallet_signing',\n label: 'Enable Embedded Wallet',\n description: 'Enable the embedded wallet for transaction signing.',\n inputType: 'boolean',\n },\n wallet_recovery_mode: {\n key: 'wallet_recovery_mode',\n label: 'Recovery Mode',\n description: 'How users can recover their wallet if they lose access.',\n inputType: 'select',\n presets: [\n { label: 'Share C Only (Recommended)', value: 'share_c_only' },\n { label: 'Full Seed Phrase', value: 'full_seed' },\n { label: 'No Recovery', value: 'none' },\n ],\n },\n feature_credits: {\n key: 'feature_credits',\n label: 'Credit System',\n description:\n 'Enable the deposits and credits system. Users can deposit tokens to receive platform credits.',\n inputType: 'boolean',\n },\n feature_user_withdrawals: {\n key: 'feature_user_withdrawals',\n label: 'User Withdrawals',\n description:\n 'Allow users to withdraw SOL/SPL tokens from their embedded wallet to external addresses.',\n inputType: 'boolean',\n },\n\n // ============= Security Settings =============\n security_cors_origins: {\n key: 'security_cors_origins',\n label: 'CORS Origins',\n description:\n 'Allowed origins for cross-origin requests (comma-separated). Empty = same origin only.',\n inputType: 'text',\n },\n security_cookie_domain: {\n key: 'security_cookie_domain',\n label: 'Cookie Domain',\n description: 'Domain for auth cookies. Empty uses the request origin.',\n inputType: 'text',\n },\n security_cookie_secure: {\n key: 'security_cookie_secure',\n label: 'Secure Cookies',\n description: 'Require HTTPS for cookies. Disable only for local development.',\n inputType: 'boolean',\n },\n security_cookie_same_site: {\n key: 'security_cookie_same_site',\n label: 'Cookie SameSite',\n description: 'SameSite policy for cookies. Use \"none\" only if needed for cross-site embeds.',\n inputType: 'select',\n presets: [\n { label: 'Strict', value: 'strict' },\n { label: 'Lax (Recommended)', value: 'lax' },\n { label: 'None (cross-site)', value: 'none' },\n ],\n },\n security_session_timeout: {\n key: 'security_session_timeout',\n label: 'Session Timeout',\n description: 'How long sessions remain valid before requiring re-authentication.',\n inputType: 'duration',\n min: 300,\n presets: [\n { label: '1 hour', value: '3600' },\n { label: '24 hours', value: '86400' },\n { label: '7 days', value: '604800' },\n { label: '30 days', value: '2592000' },\n ],\n },\n security_jwt_issuer: {\n key: 'security_jwt_issuer',\n label: 'JWT Issuer',\n description: 'Issuer claim for JWTs. Empty uses the server URL.',\n inputType: 'text',\n },\n security_jwt_audience: {\n key: 'security_jwt_audience',\n label: 'JWT Audience',\n description: 'Audience claim for JWTs. Empty uses default.',\n inputType: 'text',\n },\n\n // ============= Email/SMTP Settings =============\n email_provider: {\n key: 'email_provider',\n label: 'Email Provider',\n description: 'Select your email service provider for automatic configuration.',\n inputType: 'select',\n presets: [\n { label: 'Mailgun', value: 'mailgun' },\n { label: 'SendGrid', value: 'sendgrid' },\n { label: 'Postmark', value: 'postmark' },\n { label: 'AWS SES', value: 'ses' },\n { label: 'Resend', value: 'resend' },\n { label: 'Custom SMTP', value: 'custom' },\n ],\n },\n email_smtp_host: {\n key: 'email_smtp_host',\n label: 'SMTP Host',\n description: 'SMTP server hostname (e.g., smtp.sendgrid.net).',\n inputType: 'text',\n },\n email_smtp_port: {\n key: 'email_smtp_port',\n label: 'SMTP Port',\n description: 'SMTP server port. Common: 587 (TLS), 465 (SSL), 25 (unencrypted).',\n inputType: 'select',\n presets: [\n { label: '587 (TLS)', value: '587' },\n { label: '465 (SSL)', value: '465' },\n { label: '25 (Plain)', value: '25' },\n ],\n },\n email_smtp_user: {\n key: 'email_smtp_user',\n label: 'SMTP Username',\n description: 'Username for SMTP authentication.',\n inputType: 'text',\n },\n email_smtp_password: {\n key: 'email_smtp_password',\n label: 'API Key',\n description: 'API key or password for your email provider.',\n inputType: 'secret',\n },\n email_smtp_tls: {\n key: 'email_smtp_tls',\n label: 'Use TLS',\n description: 'Enable TLS encryption for SMTP connections.',\n inputType: 'boolean',\n },\n email_from_address: {\n key: 'email_from_address',\n label: 'From Address',\n description: 'Default sender email address (e.g., noreply@example.com).',\n inputType: 'text',\n },\n email_from_name: {\n key: 'email_from_name',\n label: 'From Name',\n description: 'Default sender display name (e.g., \"My App\").',\n inputType: 'text',\n },\n\n // ============= Webhook Settings =============\n webhook_enabled: {\n key: 'webhook_enabled',\n label: 'Enable Webhooks',\n description: 'Send notifications to a Discord or Slack webhook URL.',\n inputType: 'boolean',\n },\n webhook_url: {\n key: 'webhook_url',\n label: 'Webhook URL',\n description: 'Discord or Slack webhook URL to receive notifications.',\n inputType: 'text',\n placeholder: 'https://discord.com/api/webhooks/...',\n },\n webhook_notify_registrations: {\n key: 'webhook_notify_registrations',\n label: 'New Registrations',\n description: 'Notify when a new user registers.',\n inputType: 'boolean',\n },\n webhook_notify_signins: {\n key: 'webhook_notify_signins',\n label: 'Sign-Ins',\n description: 'Notify when a user signs in.',\n inputType: 'boolean',\n },\n webhook_notify_deposits: {\n key: 'webhook_notify_deposits',\n label: 'Deposits',\n description: 'Notify when a user makes a deposit.',\n inputType: 'boolean',\n },\n\n // ============= Server Settings =============\n server_frontend_url: {\n key: 'server_frontend_url',\n label: 'Frontend URL',\n description: 'URL of your frontend app (for redirects and email links).',\n inputType: 'text',\n },\n server_base_path: {\n key: 'server_base_path',\n label: 'Base Path',\n description: 'Base path for auth endpoints (e.g., /auth).',\n inputType: 'text',\n },\n server_trust_proxy: {\n key: 'server_trust_proxy',\n label: 'Trust Proxy',\n description: 'Trust X-Forwarded-For headers. Enable if behind a reverse proxy.',\n inputType: 'boolean',\n },\n server_cedros_pay_api_key: {\n key: 'server_cedros_pay_api_key',\n label: 'Cedros Pay API Key',\n description:\n 'API key for Cedros Pay to authenticate with this server. Copy this into your Cedros Pay settings.',\n inputType: 'secret',\n },\n jupiter_api_key: {\n key: 'jupiter_api_key',\n label: 'Jupiter API Key',\n description:\n '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>.',\n inputType: 'secret',\n },\n server_metrics_api_key: {\n key: 'server_metrics_api_key',\n label: 'Metrics API Key',\n description:\n 'API key for Prometheus/Grafana to scrape the /metrics endpoint. Use with Authorization: Bearer header.',\n inputType: 'secret',\n },\n server_log_level: {\n key: 'server_log_level',\n label: 'Log Level',\n description: 'Minimum severity level for log output. Lower levels are more verbose.',\n inputType: 'select',\n presets: [\n { label: 'Trace (most verbose)', value: 'trace' },\n { label: 'Debug', value: 'debug' },\n { label: 'Info', value: 'info' },\n { label: 'Warn', value: 'warn' },\n { label: 'Error (least verbose)', value: 'error' },\n ],\n },\n server_log_format: {\n key: 'server_log_format',\n label: 'Log Format',\n description: 'Output format for log messages.',\n inputType: 'select',\n presets: [\n { label: 'JSON (structured)', value: 'json' },\n { label: 'Pretty (human-readable)', value: 'pretty' },\n ],\n },\n server_environment: {\n key: 'server_environment',\n label: 'Environment',\n description: 'Deployment environment. Affects default behaviors and log verbosity.',\n inputType: 'select',\n presets: [\n { label: 'Development', value: 'development' },\n { label: 'Staging', value: 'staging' },\n { label: 'Production', value: 'production' },\n ],\n },\n\n // ============= Privacy Settings (existing) =============\n privacy_period_secs: {\n key: 'privacy_period_secs',\n label: 'Privacy Period',\n description:\n 'How long deposits are held before withdrawal to provide timing privacy. Longer periods provide better privacy but delay user access to funds.',\n inputType: 'duration',\n min: 0,\n presets: [\n { label: 'Disabled', value: '0' },\n { label: '1 hour', value: '3600' },\n { label: '6 hours', value: '21600' },\n { label: '24 hours', value: '86400' },\n { label: '7 days', value: '604800' },\n { label: '14 days', value: '1209600' },\n { label: '30 days', value: '2592000' },\n ],\n warningThreshold: {\n below: 3600,\n message: 'Very short privacy periods may not provide adequate timing protection.',\n },\n },\n\n // Treasury settings\n treasury_wallet_address: {\n key: 'treasury_wallet_address',\n label: 'Treasury Wallet Address',\n description:\n 'Solana wallet address where funds are sent. Used for privacy cash withdrawals, micro payment batches, and direct payments.',\n inputType: 'text',\n placeholder: 'e.g., 7xKXtg2CW87d97TXJSDpbD5jBkheTqA83TZRuJosgAsU',\n },\n\n // Withdrawal worker settings\n withdrawal_poll_interval_secs: {\n key: 'withdrawal_poll_interval_secs',\n label: 'Worker Poll Interval',\n description:\n 'How often the withdrawal worker checks for deposits ready to process. Lower values process faster but increase server load.',\n inputType: 'duration',\n min: 60,\n presets: [\n { label: '1 minute', value: '60' },\n { label: '5 minutes', value: '300' },\n { label: '15 minutes', value: '900' },\n { label: '1 hour', value: '3600' },\n { label: '6 hours', value: '21600' },\n ],\n warningThreshold: {\n below: 60,\n message: 'Polling more than once per minute may cause excessive load.',\n },\n },\n withdrawal_batch_size: {\n key: 'withdrawal_batch_size',\n label: 'Batch Size',\n description:\n 'Maximum number of withdrawals to process in a single batch. Higher values improve throughput but may cause timeouts.',\n inputType: 'select',\n min: 1,\n max: 100,\n presets: [\n { label: '1 (Sequential)', value: '1' },\n { label: '5', value: '5' },\n { label: '10 (Recommended)', value: '10' },\n { label: '25', value: '25' },\n { label: '50', value: '50' },\n { label: '100 (Max)', value: '100' },\n ],\n },\n withdrawal_timeout_secs: {\n key: 'withdrawal_timeout_secs',\n label: 'Transaction Timeout',\n description:\n 'How long to wait for a withdrawal transaction to confirm before considering it failed.',\n inputType: 'duration',\n min: 30,\n presets: [\n { label: '30 seconds', value: '30' },\n { label: '1 minute', value: '60' },\n { label: '2 minutes', value: '120' },\n { label: '5 minutes', value: '300' },\n ],\n warningThreshold: {\n below: 30,\n message: 'Very short timeouts may cause premature failure on slow networks.',\n },\n },\n withdrawal_max_retries: {\n key: 'withdrawal_max_retries',\n label: 'Max Retries',\n description:\n 'Number of times to retry a failed withdrawal before marking it as permanently failed.',\n inputType: 'select',\n min: 0,\n max: 10,\n presets: [\n { label: '0 (No retries)', value: '0' },\n { label: '1', value: '1' },\n { label: '3 (Recommended)', value: '3' },\n { label: '5', value: '5' },\n { label: '10', value: '10' },\n ],\n },\n withdrawal_percentage: {\n key: 'withdrawal_percentage',\n label: 'Withdrawal Percentage',\n description:\n 'Percentage of ready funds to withdraw each cycle. Lower values spread withdrawals over time for better privacy.',\n inputType: 'percentage',\n min: 1,\n max: 100,\n step: 5,\n presets: [\n { label: '25%', value: '25' },\n { label: '50%', value: '50' },\n { label: '75%', value: '75' },\n { label: '100% (All at once)', value: '100' },\n ],\n warningThreshold: {\n above: 75,\n message:\n 'High percentages may reduce timing privacy by processing most withdrawals together.',\n },\n },\n partial_withdrawal_count: {\n key: 'partial_withdrawal_count',\n label: 'Partial Withdrawals',\n description:\n 'Maximum partial withdrawals per batch. Partial withdrawals add noise to timing analysis. Set to 0 to disable.',\n inputType: 'select',\n min: 0,\n presets: [\n { label: 'Disabled', value: '0' },\n { label: '1', value: '1' },\n { label: '3', value: '3' },\n { label: '5', value: '5' },\n { label: '10', value: '10' },\n ],\n },\n partial_withdrawal_min_lamports: {\n key: 'partial_withdrawal_min_lamports',\n label: 'Min Balance for Partial',\n description:\n 'Minimum account balance (in lamports) required before partial withdrawals are considered. 1 SOL = 1,000,000,000 lamports.',\n inputType: 'select',\n min: 0,\n presets: [\n { label: '0.1 SOL', value: '100000000' },\n { label: '0.5 SOL', value: '500000000' },\n { label: '1 SOL', value: '1000000000' },\n { label: '5 SOL', value: '5000000000' },\n { label: '10 SOL', value: '10000000000' },\n ],\n },\n\n // Rate limit settings\n rate_limit_auth: {\n key: 'rate_limit_auth',\n label: 'Auth Request Limit',\n description:\n 'Maximum authentication attempts (login, register, password reset) per IP per window. Protects against brute force attacks.',\n inputType: 'select',\n min: 1,\n unit: 'requests',\n presets: [\n { label: '5 (Strict)', value: '5' },\n { label: '10 (Recommended)', value: '10' },\n { label: '20', value: '20' },\n { label: '50 (Permissive)', value: '50' },\n ],\n warningThreshold: {\n above: 20,\n message: 'High auth limits may allow brute force attempts.',\n },\n },\n rate_limit_general: {\n key: 'rate_limit_general',\n label: 'General Request Limit',\n description: 'Maximum general API requests per IP per window. Affects all non-auth endpoints.',\n inputType: 'select',\n min: 1,\n unit: 'requests',\n presets: [\n { label: '30', value: '30' },\n { label: '60 (Recommended)', value: '60' },\n { label: '120', value: '120' },\n { label: '300', value: '300' },\n ],\n },\n rate_limit_credit: {\n key: 'rate_limit_credit',\n label: 'Credit Request Limit',\n description:\n 'Maximum credit/balance check requests per IP per window. Higher for apps that poll balance frequently.',\n inputType: 'select',\n min: 1,\n unit: 'requests',\n presets: [\n { label: '10', value: '10' },\n { label: '30 (Recommended)', value: '30' },\n { label: '60', value: '60' },\n { label: '120', value: '120' },\n ],\n },\n rate_limit_window: {\n key: 'rate_limit_window',\n label: 'Rate Limit Window',\n description:\n 'Time window for rate limiting. All limits above are \"per window\". Shorter windows are stricter.',\n inputType: 'duration',\n min: 1,\n presets: [\n { label: '30 seconds', value: '30' },\n { label: '1 minute', value: '60' },\n { label: '5 minutes', value: '300' },\n { label: '15 minutes', value: '900' },\n ],\n },\n\n // ============= Deposit General Settings =============\n solana_rpc_url: {\n key: 'solana_rpc_url',\n label: 'Solana RPC URL',\n description:\n '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>.',\n inputType: 'text',\n placeholder: 'https://api.mainnet-beta.solana.com',\n },\n solana_network: {\n key: 'solana_network',\n label: 'Solana Network',\n description: 'The Solana network to use for deposits and withdrawals.',\n inputType: 'select',\n presets: [\n { label: 'Mainnet', value: 'mainnet-beta' },\n { label: 'Devnet', value: 'devnet' },\n ],\n },\n deposit_privacy_enabled: {\n key: 'deposit_privacy_enabled',\n label: 'Enable Private Deposits',\n description:\n 'When enabled, deposits are held for a privacy period before withdrawal. Provides timing privacy but delays fund availability.',\n inputType: 'boolean',\n },\n deposit_company_token: {\n key: 'deposit_company_token',\n label: 'Platform Token',\n description:\n 'The token that represents platform credits. Deposits are converted to this token. Common choices: USDC, SOL.',\n inputType: 'select',\n presets: [\n { label: 'USDC', value: 'USDC' },\n { label: 'USDT', value: 'USDT' },\n { label: 'SOL', value: 'SOL' },\n { label: 'EURC', value: 'EURC' },\n ],\n },\n deposit_micro_enabled: {\n key: 'deposit_micro_enabled',\n label: 'SOL Micro Payments',\n description: 'Allow small SOL deposits (under $10) that are batched together for efficiency.',\n inputType: 'boolean',\n },\n deposit_gasless_swap_enabled: {\n key: 'deposit_gasless_swap_enabled',\n label: 'Gasless Swap Payments',\n description: 'Allow deposits via Jupiter swaps.',\n inputType: 'boolean',\n },\n deposit_min_usd: {\n key: 'deposit_min_usd',\n label: 'Minimum Deposit',\n description: 'Minimum deposit amount in USD equivalent.',\n inputType: 'select',\n unit: 'USD',\n presets: [\n { label: '$1', value: '1' },\n { label: '$5', value: '5' },\n { label: '$10', value: '10' },\n { label: '$25', value: '25' },\n ],\n },\n deposit_max_usd: {\n key: 'deposit_max_usd',\n label: 'Maximum Deposit',\n description:\n 'Maximum deposit amount per transaction in USD equivalent. Set to 0 for unlimited.',\n inputType: 'select',\n unit: 'USD',\n presets: [\n { label: 'Unlimited', value: '0' },\n { label: '$1,000', value: '1000' },\n { label: '$10,000', value: '10000' },\n { label: '$100,000', value: '100000' },\n ],\n },\n\n // Deposit component settings\n deposit_show_explainer: {\n key: 'deposit_show_explainer',\n label: 'Show Explainer Screen',\n description: 'Show the introductory explainer screen at the start of the deposit flow.',\n inputType: 'boolean',\n },\n\n // Deposit token settings\n deposit_quick_action_tokens: {\n key: 'deposit_quick_action_tokens',\n label: 'Quick Action Tokens',\n description:\n 'Comma-separated token symbols shown as quick action buttons. First token is the default.',\n inputType: 'tokenSymbolList',\n },\n deposit_custom_tokens: {\n key: 'deposit_custom_tokens',\n label: 'Custom Dropdown Tokens',\n description:\n 'Comma-separated token symbols shown in the \"Custom\" dropdown. Leave empty to show all.',\n inputType: 'tokenSymbolList',\n },\n deposit_custom_tokens_json: {\n key: 'deposit_custom_tokens_json',\n label: 'Custom Token Definitions',\n description:\n 'Add tokens beyond the built-in list. Define symbol, mint address, decimals, and logo URL.',\n inputType: 'tokenList',\n },\n\n // Deposit fee settings\n deposit_fee_policy: {\n key: 'deposit_fee_policy',\n label: 'Fee Policy',\n description: 'Who pays deposit fees: company absorbs all, or user pays swap/privacy/all fees.',\n inputType: 'select',\n presets: [\n { label: 'Company Pays All', value: 'company_pays_all' },\n { label: 'User Pays Swap Fees', value: 'user_pays_swap' },\n { label: 'User Pays Privacy Fees', value: 'user_pays_privacy' },\n { label: 'User Pays All Fees', value: 'user_pays_all' },\n ],\n },\n privacy_fee_fixed_lamports: {\n key: 'privacy_fee_fixed_lamports',\n label: 'Privacy Fixed Fee',\n description: 'Fixed fee for Privacy Cash deposits in lamports. 1 SOL = 1,000,000,000 lamports.',\n inputType: 'select',\n unit: 'lamports',\n presets: [\n { label: '0 SOL', value: '0' },\n { label: '0.001 SOL', value: '1000000' },\n { label: '0.005 SOL', value: '5000000' },\n { label: '0.006 SOL (Default)', value: '6000000' },\n { label: '0.01 SOL', value: '10000000' },\n ],\n },\n privacy_fee_percent_bps: {\n key: 'privacy_fee_percent_bps',\n label: 'Privacy Percentage Fee',\n description: 'Percentage fee for Privacy Cash deposits in basis points. 100 bps = 1%.',\n inputType: 'select',\n unit: 'bps',\n presets: [\n { label: '0%', value: '0' },\n { label: '0.25%', value: '25' },\n { label: '0.35% (Default)', value: '35' },\n { label: '0.5%', value: '50' },\n { label: '1%', value: '100' },\n ],\n },\n swap_fee_fixed_lamports: {\n key: 'swap_fee_fixed_lamports',\n label: 'Swap Fixed Fee',\n description: 'Fixed fee for Jupiter swaps in lamports. Covers transaction costs.',\n inputType: 'select',\n unit: 'lamports',\n presets: [\n { label: '0 SOL', value: '0' },\n { label: '0.001 SOL (Default)', value: '1000000' },\n { label: '0.002 SOL', value: '2000000' },\n { label: '0.005 SOL', value: '5000000' },\n ],\n },\n swap_fee_percent_bps: {\n key: 'swap_fee_percent_bps',\n label: 'Swap Percentage Fee',\n description: 'Percentage fee for Jupiter swaps in basis points. 100 bps = 1%.',\n inputType: 'select',\n unit: 'bps',\n presets: [\n { label: '0%', value: '0' },\n { label: '0.1% (Default)', value: '10' },\n { label: '0.25%', value: '25' },\n { label: '0.5%', value: '50' },\n ],\n },\n company_fee_fixed_lamports: {\n key: 'company_fee_fixed_lamports',\n label: 'Company Fixed Fee',\n description: 'Additional fixed processing fee in lamports. Set to 0 to disable.',\n inputType: 'select',\n unit: 'lamports',\n presets: [\n { label: 'Disabled', value: '0' },\n { label: '0.001 SOL', value: '1000000' },\n { label: '0.005 SOL', value: '5000000' },\n { label: '0.01 SOL', value: '10000000' },\n ],\n },\n company_fee_percent_bps: {\n key: 'company_fee_percent_bps',\n label: 'Company Percentage Fee',\n description: 'Additional percentage processing fee in basis points. 100 bps = 1%.',\n inputType: 'select',\n unit: 'bps',\n presets: [\n { label: 'Disabled', value: '0' },\n { label: '0.1%', value: '10' },\n { label: '0.25%', value: '25' },\n { label: '0.5%', value: '50' },\n { label: '1%', value: '100' },\n ],\n },\n micro_batch_threshold_usd: {\n key: 'micro_batch_threshold_usd',\n label: 'Batch Threshold',\n description:\n 'Minimum accumulated USD value before triggering a batch swap. Jupiter requires ~$10 minimum.',\n inputType: 'select',\n unit: 'USD',\n presets: [\n { label: '$10 (Minimum)', value: '10' },\n { label: '$25', value: '25' },\n { label: '$50', value: '50' },\n { label: '$100', value: '100' },\n ],\n },\n micro_batch_poll_secs: {\n key: 'micro_batch_poll_secs',\n label: 'Batch Poll Interval',\n description:\n 'How often to check for batchable micro deposits. Lower values process faster but increase load.',\n inputType: 'duration',\n min: 60,\n presets: [\n { label: '1 minute', value: '60' },\n { label: '5 minutes (Default)', value: '300' },\n { label: '15 minutes', value: '900' },\n { label: '1 hour', value: '3600' },\n ],\n },\n private_deposit_min_lamports: {\n key: 'private_deposit_min_lamports',\n label: 'Min Private Deposit',\n description:\n 'Minimum amount for Privacy Cash deposits in lamports. Smaller deposits use micro batching.',\n inputType: 'select',\n unit: 'lamports',\n presets: [\n { label: '0.1 SOL', value: '100000000' },\n { label: '0.25 SOL (Default)', value: '250000000' },\n { label: '0.5 SOL', value: '500000000' },\n { label: '1 SOL', value: '1000000000' },\n ],\n },\n withdrawal_min_lamports: {\n key: 'withdrawal_min_lamports',\n label: 'Min Withdrawal Amount',\n description:\n 'Minimum amount to withdraw in lamports. Deposits below this remain pending. Fees are ~0.006 SOL + 0.35% + Jupiter.',\n inputType: 'select',\n unit: 'lamports',\n presets: [\n { label: '0.5 SOL', value: '500000000' },\n { label: '1 SOL (Default)', value: '1000000000' },\n { label: '2 SOL', value: '2000000000' },\n { label: '5 SOL', value: '5000000000' },\n ],\n warningThreshold: {\n below: 500000000,\n message: 'Very small withdrawals may lose significant value to fees.',\n },\n },\n};\n\n// =============================================================================\n// CATEGORY METADATA\n// =============================================================================\n\nexport interface CategoryMeta {\n label: string;\n description: string;\n icon: string;\n}\n\nexport const CATEGORY_METADATA: Record<string, CategoryMeta> = {\n // Auth providers (sorted alphabetically by subcategory)\n 'auth.apple': {\n label: 'Apple Sign-In',\n description: 'Configure Sign in with Apple OAuth integration.',\n icon: '',\n },\n 'auth.email': {\n label: 'Email Authentication',\n description: 'Configure email/password authentication settings.',\n icon: '',\n },\n 'auth.google': {\n label: 'Google Sign-In',\n description: 'Configure Google OAuth integration.',\n icon: '',\n },\n 'auth.solana': {\n label: 'Solana Wallet Auth',\n description: 'Configure Solana wallet signature authentication.',\n icon: '',\n },\n 'auth.webauthn': {\n label: 'WebAuthn / Passkeys',\n description: 'Configure FIDO2/WebAuthn passwordless authentication.',\n icon: '',\n },\n 'auth.instantlink': {\n label: 'Instant Link',\n description: 'Configure magic link passwordless authentication via email.',\n icon: '',\n },\n 'deposit.general': {\n label: 'General',\n description: 'Core deposit and credit system configuration.',\n icon: '',\n },\n deposit: {\n label: 'Deposit Settings',\n description: 'Configure deposit tokens, fees, and related settings.',\n icon: '',\n },\n email: {\n label: 'Email / SMTP',\n description:\n 'Configure outbound email delivery for verification, password reset, and notifications.',\n icon: '',\n },\n features: {\n label: 'Feature Flags',\n description: 'Enable or disable major platform features.',\n icon: '',\n },\n privacy: {\n label: 'Privacy Settings',\n description:\n 'Control the privacy period for deposits. Longer periods provide better timing privacy but delay fund availability.',\n icon: '',\n },\n rate_limit: {\n label: 'Rate Limiting',\n description:\n 'Protect the system from abuse by limiting request rates. Balance security with user experience.',\n icon: '',\n },\n security: {\n label: 'Security',\n description: 'Configure CORS, cookies, sessions, and JWT settings.',\n icon: '',\n },\n server: {\n label: 'Server',\n description: 'Server infrastructure settings. Some may be overridden by environment variables.',\n icon: '',\n },\n webhook: {\n label: 'Webhooks',\n description: 'Configure HTTP webhook notifications for auth events.',\n icon: '',\n },\n withdrawal: {\n label: 'Withdrawal Worker',\n description:\n 'Configure how the automated withdrawal processor handles pending withdrawals. These settings affect throughput and privacy.',\n icon: '',\n },\n};\n\n/** Preset tokens that are always available without needing to be redefined */\nexport const PRESET_TOKEN_SYMBOLS = [\n 'SOL',\n 'USDC',\n 'USDT',\n 'EURC',\n 'USD1',\n 'PYUSD',\n 'USDH',\n 'CASH',\n 'BONK',\n 'ORE',\n];\n","/**\n * Settings input components - reusable inputs for system settings\n */\nimport { useState, useCallback, useMemo, type ReactNode } from 'react';\nimport type { SystemSetting, SettingMeta } from '../../../types';\nimport { formatDuration, SETTING_METADATA, PRESET_TOKEN_SYMBOLS } from './settingsMetadata';\n\n/** UI-01: Safely render description text that may contain simple <a> tags */\nfunction renderDescription(html: string): ReactNode {\n // Split on <a href=\"...\">...</a> pattern, render links as React elements\n const parts = html.split(/(<a\\s[^>]*>.*?<\\/a>)/g);\n if (parts.length === 1) return html;\n return parts.map((part, i) => {\n const match = part.match(/^<a\\s+href=\"([^\"]+)\"[^>]*>([^<]+)<\\/a>$/);\n if (match) {\n return (\n <a key={i} href={match[1]} target=\"_blank\" rel=\"noopener noreferrer\">\n {match[2]}\n </a>\n );\n }\n return part;\n });\n}\n\n// =============================================================================\n// SETTINGS SECTION\n// =============================================================================\n\nexport interface SettingsSectionProps {\n settings: SystemSetting[];\n edits: Record<string, string>;\n onChange: (key: string, value: string) => void;\n /** External warnings keyed by setting key */\n externalWarnings?: Record<string, string>;\n}\n\nexport function SettingsSection({\n settings,\n edits,\n onChange,\n externalWarnings,\n}: SettingsSectionProps) {\n return (\n <div className=\"cedros-settings-grid\">\n {settings.map((setting) => (\n <SettingRow\n key={setting.key}\n setting={setting}\n editValue={edits[setting.key]}\n onChange={onChange}\n externalWarning={externalWarnings?.[setting.key]}\n />\n ))}\n </div>\n );\n}\n\n// =============================================================================\n// SETTING ROW\n// =============================================================================\n\ninterface SettingRowProps {\n setting: SystemSetting;\n editValue?: string;\n onChange: (key: string, value: string) => void;\n /** External warning message that overrides threshold-based warnings */\n externalWarning?: string;\n}\n\nexport function SettingRow({ setting, editValue, onChange, externalWarning }: SettingRowProps) {\n const meta = SETTING_METADATA[setting.key];\n const currentValue = editValue ?? setting.value;\n const hasChange = editValue !== undefined && editValue !== setting.value;\n const isBoolean = meta?.inputType === 'boolean';\n\n // Check for warnings (external warnings take precedence)\n const warning = useMemo(() => {\n if (externalWarning) return externalWarning;\n if (!meta?.warningThreshold) return null;\n const numValue = parseInt(currentValue, 10);\n if (isNaN(numValue)) return null;\n const { above, below, message } = meta.warningThreshold;\n if (above !== undefined && numValue > above) return message;\n if (below !== undefined && numValue < below) return message;\n return null;\n }, [currentValue, meta?.warningThreshold, externalWarning]);\n\n if (!meta) {\n // Fallback for unknown settings\n return (\n <div className={`cedros-setting-row ${hasChange ? 'cedros-setting-row-changed' : ''}`}>\n <div className=\"cedros-setting-label\">\n <span className=\"cedros-setting-name\">{setting.key}</span>\n {setting.description && (\n <span className=\"cedros-setting-description\">{setting.description}</span>\n )}\n </div>\n <div className=\"cedros-setting-input-wrapper\">\n <input\n type=\"text\"\n value={currentValue}\n onChange={(e) => onChange(setting.key, e.target.value)}\n className=\"cedros-setting-input\"\n />\n </div>\n </div>\n );\n }\n\n return (\n <div\n className={`cedros-setting-row ${hasChange ? 'cedros-setting-row-changed' : ''} ${warning ? 'cedros-setting-row-warning' : ''} ${isBoolean ? 'cedros-setting-row-toggle' : ''}`}\n >\n {isBoolean ? (\n <>\n <div className=\"cedros-setting-control cedros-setting-control-toggle\">\n <SettingInput\n meta={meta}\n value={currentValue}\n onChange={(value) => onChange(setting.key, value)}\n />\n {warning && <div className=\"cedros-setting-warning\">{warning}</div>}\n </div>\n <div className=\"cedros-setting-label\">\n <span className=\"cedros-setting-name\">{meta.label}</span>\n <span className=\"cedros-setting-description\">\n {renderDescription(meta.description)}\n </span>\n </div>\n </>\n ) : (\n <>\n <div className=\"cedros-setting-label\">\n <span className=\"cedros-setting-name\">{meta.label}</span>\n <span className=\"cedros-setting-description\">\n {renderDescription(meta.description)}\n </span>\n </div>\n\n <div className=\"cedros-setting-control\">\n <SettingInput\n meta={meta}\n value={currentValue}\n onChange={(value) => onChange(setting.key, value)}\n />\n {warning && <div className=\"cedros-setting-warning\">{warning}</div>}\n </div>\n </>\n )}\n </div>\n );\n}\n\n// =============================================================================\n// SETTING INPUT - Renders the appropriate input based on type\n// =============================================================================\n\ninterface SettingInputProps {\n meta: SettingMeta;\n value: string;\n onChange: (value: string) => void;\n}\n\nfunction SettingInput({ meta, value, onChange }: SettingInputProps) {\n switch (meta.inputType) {\n case 'duration':\n return (\n <DurationInput value={value} onChange={onChange} presets={meta.presets} min={meta.min} />\n );\n case 'percentage':\n return (\n <PercentageInput\n value={value}\n onChange={onChange}\n min={meta.min ?? 1}\n max={meta.max ?? 100}\n step={meta.step ?? 5}\n presets={meta.presets}\n />\n );\n case 'select':\n return (\n <SelectInput\n value={value}\n onChange={onChange}\n presets={meta.presets ?? []}\n unit={meta.unit}\n />\n );\n case 'number':\n return (\n <NumberInput\n value={value}\n onChange={onChange}\n min={meta.min}\n max={meta.max}\n unit={meta.unit}\n />\n );\n case 'tokenList':\n return <TokenListInput value={value} onChange={onChange} />;\n case 'text':\n return (\n <input\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n className=\"cedros-setting-input\"\n placeholder={meta.label}\n />\n );\n case 'boolean':\n return <BooleanInput value={value} onChange={onChange} />;\n case 'secret':\n return <SecretInput value={value} onChange={onChange} multiline={meta.multiline} />;\n case 'tokenSymbolList':\n return <TokenSymbolListInput value={value} onChange={onChange} />;\n default:\n return (\n <input\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n className=\"cedros-setting-input\"\n />\n );\n }\n}\n\n// =============================================================================\n// DURATION INPUT\n// =============================================================================\n\ninterface DurationInputProps {\n value: string;\n onChange: (value: string) => void;\n presets?: { label: string; value: string }[];\n min?: number;\n}\n\nexport function DurationInput({ value, onChange, presets, min = 0 }: DurationInputProps) {\n const numValue = parseInt(value, 10) || 0;\n const displayValue = formatDuration(numValue);\n\n const handlePresetChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n if (e.target.value) {\n onChange(e.target.value);\n }\n },\n [onChange]\n );\n\n const handleCustomChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = Math.max(min, parseInt(e.target.value, 10) || 0);\n onChange(String(newValue));\n },\n [onChange, min]\n );\n\n return (\n <div className=\"cedros-duration-input\">\n {presets && presets.length > 0 && (\n <select\n value={presets.find((p) => p.value === value)?.value ?? ''}\n onChange={handlePresetChange}\n className=\"cedros-setting-select\"\n >\n <option value=\"\">Custom...</option>\n {presets.map((preset) => (\n <option key={preset.value} value={preset.value}>\n {preset.label}\n </option>\n ))}\n </select>\n )}\n <div className=\"cedros-duration-custom\">\n <input\n type=\"number\"\n value={numValue}\n onChange={handleCustomChange}\n min={min}\n className=\"cedros-setting-input cedros-setting-input-sm\"\n />\n <span className=\"cedros-setting-unit\">seconds</span>\n <span className=\"cedros-duration-display\">= {displayValue}</span>\n </div>\n </div>\n );\n}\n\n// =============================================================================\n// PERCENTAGE INPUT\n// =============================================================================\n\ninterface PercentageInputProps {\n value: string;\n onChange: (value: string) => void;\n min: number;\n max: number;\n step: number;\n presets?: { label: string; value: string }[];\n}\n\nexport function PercentageInput({\n value,\n onChange,\n min,\n max,\n step,\n presets,\n}: PercentageInputProps) {\n const numValue = parseInt(value, 10) || min;\n\n const handleSliderChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.value);\n },\n [onChange]\n );\n\n const handlePresetClick = useCallback(\n (presetValue: string) => {\n onChange(presetValue);\n },\n [onChange]\n );\n\n return (\n <div className=\"cedros-percentage-input\">\n <div className=\"cedros-percentage-slider-row\">\n <input\n type=\"range\"\n value={numValue}\n onChange={handleSliderChange}\n min={min}\n max={max}\n step={step}\n className=\"cedros-percentage-slider\"\n />\n <span className=\"cedros-percentage-value\">{numValue}%</span>\n </div>\n {presets && presets.length > 0 && (\n <div className=\"cedros-preset-buttons\">\n {presets.map((preset) => (\n <button\n key={preset.value}\n type=\"button\"\n className={`cedros-preset-button ${preset.value === value ? 'cedros-preset-button-active' : ''}`}\n onClick={() => handlePresetClick(preset.value)}\n >\n {preset.label}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n\n// =============================================================================\n// SELECT INPUT\n// =============================================================================\n\ninterface SelectInputProps {\n value: string;\n onChange: (value: string) => void;\n presets: { label: string; value: string }[];\n unit?: string;\n}\n\nexport function SelectInput({ value, onChange, presets, unit }: SelectInputProps) {\n const isCustomValue = !presets.some((p) => p.value === value);\n\n const handleSelectChange = useCallback(\n (e: React.ChangeEvent<HTMLSelectElement>) => {\n if (e.target.value !== '__custom__') {\n onChange(e.target.value);\n }\n },\n [onChange]\n );\n\n const handleCustomChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.value);\n },\n [onChange]\n );\n\n return (\n <div className=\"cedros-select-input\">\n <select\n value={isCustomValue ? '__custom__' : value}\n onChange={handleSelectChange}\n className=\"cedros-setting-select\"\n >\n {presets.map((preset) => (\n <option key={preset.value} value={preset.value}>\n {preset.label}\n </option>\n ))}\n <option value=\"__custom__\">Custom...</option>\n </select>\n {isCustomValue && (\n <div className=\"cedros-select-custom\">\n <input\n type=\"number\"\n value={value}\n onChange={handleCustomChange}\n className=\"cedros-setting-input cedros-setting-input-sm\"\n />\n {unit && <span className=\"cedros-setting-unit\">{unit}</span>}\n </div>\n )}\n </div>\n );\n}\n\n// =============================================================================\n// NUMBER INPUT\n// =============================================================================\n\ninterface NumberInputProps {\n value: string;\n onChange: (value: string) => void;\n min?: number;\n max?: number;\n unit?: string;\n}\n\nexport function NumberInput({ value, onChange, min, max, unit }: NumberInputProps) {\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n onChange(e.target.value);\n },\n [onChange]\n );\n\n return (\n <div className=\"cedros-number-input\">\n <input\n type=\"number\"\n value={value}\n onChange={handleChange}\n min={min}\n max={max}\n className=\"cedros-setting-input\"\n />\n {unit && <span className=\"cedros-setting-unit\">{unit}</span>}\n </div>\n );\n}\n\n// =============================================================================\n// BOOLEAN INPUT (Toggle)\n// =============================================================================\n\ninterface BooleanInputProps {\n value: string;\n onChange: (value: string) => void;\n}\n\nexport function BooleanInput({ value, onChange }: BooleanInputProps) {\n const isEnabled = value === 'true';\n\n const handleToggle = useCallback(() => {\n onChange(isEnabled ? 'false' : 'true');\n }, [isEnabled, onChange]);\n\n return (\n <button\n type=\"button\"\n role=\"switch\"\n aria-checked={isEnabled}\n className={`cedros-toggle ${isEnabled ? 'cedros-toggle-on' : 'cedros-toggle-off'}`}\n onClick={handleToggle}\n >\n <span className=\"cedros-toggle-track\">\n <span className=\"cedros-toggle-thumb\" />\n </span>\n <span className=\"cedros-toggle-label\">{isEnabled ? 'Enabled' : 'Disabled'}</span>\n </button>\n );\n}\n\n// =============================================================================\n// SECRET INPUT (Masked)\n// =============================================================================\n\ninterface SecretInputProps {\n value: string;\n onChange: (value: string) => void;\n multiline?: boolean;\n}\n\nexport function SecretInput({ value, onChange, multiline }: SecretInputProps) {\n const [isEditing, setIsEditing] = useState(false);\n const [showValue, setShowValue] = useState(false);\n const hasValue = value && value.length > 0;\n\n const handleEdit = useCallback(() => {\n setIsEditing(true);\n setShowValue(true);\n }, []);\n\n const handleDone = useCallback(() => {\n setIsEditing(false);\n setShowValue(false);\n }, []);\n\n const handleChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {\n onChange(e.target.value);\n },\n [onChange]\n );\n\n if (!isEditing && hasValue) {\n return (\n <div className=\"cedros-secret-input cedros-secret-input-masked\">\n <span className=\"cedros-secret-masked\">{'•'.repeat(Math.min(value.length, 20))}</span>\n <button type=\"button\" className=\"cedros-secret-edit-btn\" onClick={handleEdit}>\n Edit\n </button>\n </div>\n );\n }\n\n return (\n <div className=\"cedros-secret-input\">\n {multiline ? (\n <textarea\n value={value}\n onChange={handleChange}\n className=\"cedros-setting-input cedros-setting-textarea\"\n placeholder=\"Enter secret value...\"\n rows={4}\n />\n ) : (\n <input\n type={showValue ? 'text' : 'password'}\n value={value}\n onChange={handleChange}\n className=\"cedros-setting-input\"\n placeholder=\"Enter secret value...\"\n />\n )}\n <div className=\"cedros-secret-actions\">\n {!multiline && (\n <button\n type=\"button\"\n className=\"cedros-secret-toggle-btn\"\n onClick={() => setShowValue(!showValue)}\n >\n {showValue ? 'Hide' : 'Show'}\n </button>\n )}\n {isEditing && (\n <button type=\"button\" className=\"cedros-secret-done-btn\" onClick={handleDone}>\n Done\n </button>\n )}\n </div>\n </div>\n );\n}\n\n// =============================================================================\n// TOKEN LIST INPUT\n// =============================================================================\n\ninterface TokenDefinition {\n symbol: string;\n mint: string;\n decimals: number;\n logoUrl?: string;\n}\n\ninterface TokenListInputProps {\n value: string;\n onChange: (value: string) => void;\n}\n\nexport function TokenListInput({ value, onChange }: TokenListInputProps) {\n const tokens: TokenDefinition[] = useMemo(() => {\n try {\n return JSON.parse(value || '[]');\n } catch {\n return [];\n }\n }, [value]);\n\n const updateTokens = useCallback(\n (updated: TokenDefinition[]) => {\n onChange(JSON.stringify(updated));\n },\n [onChange]\n );\n\n const addToken = useCallback(() => {\n updateTokens([...tokens, { symbol: '', mint: '', decimals: 6 }]);\n }, [tokens, updateTokens]);\n\n const updateToken = useCallback(\n (index: number, field: keyof TokenDefinition, val: string | number | undefined) => {\n const updated = [...tokens];\n updated[index] = { ...updated[index], [field]: val };\n updateTokens(updated);\n },\n [tokens, updateTokens]\n );\n\n const removeToken = useCallback(\n (index: number) => {\n updateTokens(tokens.filter((_, i) => i !== index));\n },\n [tokens, updateTokens]\n );\n\n return (\n <div className=\"cedros-token-list-input\">\n {/* Preset tokens info */}\n <div className=\"cedros-token-presets\">\n <span className=\"cedros-token-presets-label\">Built-in tokens:</span>\n <div className=\"cedros-token-presets-list\">\n {PRESET_TOKEN_SYMBOLS.map((symbol) => (\n <span key={symbol} className=\"cedros-token-preset-chip\">\n {symbol}\n </span>\n ))}\n </div>\n </div>\n\n {tokens.length === 0 && (\n <p className=\"cedros-token-list-empty\">\n No custom tokens added. Use the built-in tokens above or add your own.\n </p>\n )}\n\n {tokens.map((token, i) => (\n <div key={i} className=\"cedros-token-row\">\n <div className=\"cedros-token-row-fields\">\n <input\n type=\"text\"\n placeholder=\"Symbol\"\n value={token.symbol}\n onChange={(e) => updateToken(i, 'symbol', e.target.value.toUpperCase())}\n className=\"cedros-setting-input cedros-token-input-symbol\"\n maxLength={10}\n />\n <input\n type=\"text\"\n placeholder=\"Mint address\"\n value={token.mint}\n onChange={(e) => updateToken(i, 'mint', e.target.value)}\n className=\"cedros-setting-input cedros-token-input-mint\"\n />\n <input\n type=\"number\"\n placeholder=\"Decimals\"\n value={token.decimals}\n onChange={(e) => updateToken(i, 'decimals', parseInt(e.target.value, 10) || 0)}\n className=\"cedros-setting-input cedros-token-input-decimals\"\n min={0}\n max={18}\n />\n <input\n type=\"text\"\n placeholder=\"Logo URL (optional)\"\n value={token.logoUrl || ''}\n onChange={(e) => updateToken(i, 'logoUrl', e.target.value || undefined)}\n className=\"cedros-setting-input cedros-token-input-logo\"\n />\n </div>\n <button\n type=\"button\"\n className=\"cedros-token-remove-btn\"\n onClick={() => removeToken(i)}\n title=\"Remove token\"\n >\n ×\n </button>\n </div>\n ))}\n\n <button type=\"button\" className=\"cedros-token-add-btn\" onClick={addToken}>\n + Add Token\n </button>\n </div>\n );\n}\n\n// =============================================================================\n// TOKEN SYMBOL LIST INPUT\n// =============================================================================\n\ninterface TokenSymbolListInputProps {\n value: string;\n onChange: (value: string) => void;\n}\n\nexport function TokenSymbolListInput({ value, onChange }: TokenSymbolListInputProps) {\n const symbols = useMemo(() => {\n return value\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n }, [value]);\n\n const addSymbol = useCallback(\n (symbol: string) => {\n if (!symbol || symbols.includes(symbol)) return;\n const updated = [...symbols, symbol].join(', ');\n onChange(updated);\n },\n [symbols, onChange]\n );\n\n const removeSymbol = useCallback(\n (symbol: string) => {\n const updated = symbols.filter((s) => s !== symbol).join(', ');\n onChange(updated);\n },\n [symbols, onChange]\n );\n\n return (\n <div className=\"cedros-token-symbol-list-input\">\n {/* Preset tokens - click to add */}\n <div className=\"cedros-token-presets\">\n <span className=\"cedros-token-presets-label\">Click to add:</span>\n <div className=\"cedros-token-presets-list\">\n {PRESET_TOKEN_SYMBOLS.map((symbol) => {\n const isSelected = symbols.includes(symbol);\n return (\n <button\n key={symbol}\n type=\"button\"\n className={`cedros-token-preset-chip ${isSelected ? 'cedros-token-preset-chip-selected' : ''}`}\n onClick={() => (isSelected ? removeSymbol(symbol) : addSymbol(symbol))}\n title={isSelected ? `Remove ${symbol}` : `Add ${symbol}`}\n >\n {symbol}\n {isSelected && <span className=\"cedros-token-chip-check\">✓</span>}\n </button>\n );\n })}\n </div>\n </div>\n\n {/* Text input for manual entry or custom symbols */}\n <input\n type=\"text\"\n value={value}\n onChange={(e) => onChange(e.target.value)}\n className=\"cedros-setting-input\"\n placeholder=\"USDC, SOL, BONK...\"\n />\n </div>\n );\n}\n","/**\n * Autosave status indicator for settings pages\n */\nimport type { AutosaveStatus as Status } from '../../../hooks/useSettingsAutosave';\n\nexport interface AutosaveStatusProps {\n status: Status;\n error?: string | null;\n}\n\nexport function AutosaveStatus({ status, error }: AutosaveStatusProps) {\n if (status === 'idle') return null;\n\n return (\n <div className={`cedros-autosave-status cedros-autosave-status--${status}`}>\n {status === 'pending' && (\n <>\n <span className=\"cedros-autosave-dot\" />\n <span>Unsaved changes</span>\n </>\n )}\n {status === 'saving' && (\n <>\n <span className=\"cedros-autosave-spinner\" />\n <span>Saving...</span>\n </>\n )}\n {status === 'saved' && (\n <>\n <span className=\"cedros-autosave-check\">✓</span>\n <span>Saved</span>\n </>\n )}\n {status === 'error' && (\n <>\n <span className=\"cedros-autosave-error-icon\">!</span>\n <span>{error || 'Save failed'}</span>\n </>\n )}\n </div>\n );\n}\n"],"names":["DEBOUNCE_MS","SAVED_DISPLAY_MS","useSettingsAutosave","settings","isLoading","error","fetchSettings","updateSettings","useSystemSettings","edits","setEdits","useState","autosaveStatus","setAutosaveStatus","autosaveError","setAutosaveError","debounceTimerRef","useRef","savedTimerRef","pendingEditsRef","useEffect","performSave","useCallback","editsToSave","updates","key","value","prev","next","err","handleChange","getEffectiveValue","categorySettings","found","s","secondsToDuration","totalSeconds","days","hours","minutes","seconds","formatDuration","parts","SETTING_METADATA","PRESET_TOKEN_SYMBOLS","renderDescription","html","part","i","match","jsx","SettingsSection","onChange","externalWarnings","setting","SettingRow","editValue","externalWarning","meta","currentValue","hasChange","isBoolean","warning","useMemo","numValue","above","below","message","jsxs","Fragment","SettingInput","e","DurationInput","PercentageInput","SelectInput","NumberInput","TokenListInput","BooleanInput","SecretInput","TokenSymbolListInput","presets","min","displayValue","handlePresetChange","handleCustomChange","newValue","p","preset","max","step","handleSliderChange","handlePresetClick","presetValue","unit","isCustomValue","handleSelectChange","isEnabled","handleToggle","multiline","isEditing","setIsEditing","showValue","setShowValue","hasValue","handleEdit","handleDone","tokens","updateTokens","updated","addToken","updateToken","index","field","val","removeToken","_","symbol","token","symbols","addSymbol","removeSymbol","isSelected","AutosaveStatus","status"],"mappings":"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"}
|