@payez/next-mvp 4.0.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (459) hide show
  1. package/package.json +6 -16
  2. package/dist/api/auth-handler.d.ts +0 -66
  3. package/dist/api/auth-handler.js +0 -397
  4. package/dist/api/index.d.ts +0 -10
  5. package/dist/api/index.js +0 -19
  6. package/dist/api-handlers/account/change-password.d.ts +0 -9
  7. package/dist/api-handlers/account/change-password.js +0 -110
  8. package/dist/api-handlers/account/masked-info.d.ts +0 -2
  9. package/dist/api-handlers/account/masked-info.js +0 -41
  10. package/dist/api-handlers/account/profile.d.ts +0 -3
  11. package/dist/api-handlers/account/profile.js +0 -63
  12. package/dist/api-handlers/account/recovery/initiate.d.ts +0 -2
  13. package/dist/api-handlers/account/recovery/initiate.js +0 -26
  14. package/dist/api-handlers/account/recovery/send-code.d.ts +0 -2
  15. package/dist/api-handlers/account/recovery/send-code.js +0 -28
  16. package/dist/api-handlers/account/recovery/verify-code.d.ts +0 -2
  17. package/dist/api-handlers/account/recovery/verify-code.js +0 -28
  18. package/dist/api-handlers/account/reset-password.d.ts +0 -2
  19. package/dist/api-handlers/account/reset-password.js +0 -26
  20. package/dist/api-handlers/account/send-code.d.ts +0 -24
  21. package/dist/api-handlers/account/send-code.js +0 -60
  22. package/dist/api-handlers/account/update-phone.d.ts +0 -27
  23. package/dist/api-handlers/account/update-phone.js +0 -64
  24. package/dist/api-handlers/account/validate-password.d.ts +0 -17
  25. package/dist/api-handlers/account/validate-password.js +0 -81
  26. package/dist/api-handlers/account/verify-email.d.ts +0 -26
  27. package/dist/api-handlers/account/verify-email.js +0 -106
  28. package/dist/api-handlers/account/verify-sms.d.ts +0 -26
  29. package/dist/api-handlers/account/verify-sms.js +0 -106
  30. package/dist/api-handlers/admin/analytics.d.ts +0 -19
  31. package/dist/api-handlers/admin/analytics.js +0 -378
  32. package/dist/api-handlers/admin/audit.d.ts +0 -19
  33. package/dist/api-handlers/admin/audit.js +0 -213
  34. package/dist/api-handlers/admin/index.d.ts +0 -21
  35. package/dist/api-handlers/admin/index.js +0 -42
  36. package/dist/api-handlers/admin/redis-sessions.d.ts +0 -35
  37. package/dist/api-handlers/admin/redis-sessions.js +0 -203
  38. package/dist/api-handlers/admin/sessions.d.ts +0 -20
  39. package/dist/api-handlers/admin/sessions.js +0 -283
  40. package/dist/api-handlers/admin/site-logs.d.ts +0 -45
  41. package/dist/api-handlers/admin/site-logs.js +0 -317
  42. package/dist/api-handlers/admin/stats.d.ts +0 -20
  43. package/dist/api-handlers/admin/stats.js +0 -239
  44. package/dist/api-handlers/admin/users.d.ts +0 -19
  45. package/dist/api-handlers/admin/users.js +0 -221
  46. package/dist/api-handlers/admin/vibe-data.d.ts +0 -79
  47. package/dist/api-handlers/admin/vibe-data.js +0 -267
  48. package/dist/api-handlers/anon/preferences.d.ts +0 -37
  49. package/dist/api-handlers/anon/preferences.js +0 -96
  50. package/dist/api-handlers/auth/jwks.d.ts +0 -2
  51. package/dist/api-handlers/auth/jwks.js +0 -24
  52. package/dist/api-handlers/auth/login.d.ts +0 -42
  53. package/dist/api-handlers/auth/login.js +0 -178
  54. package/dist/api-handlers/auth/refresh.d.ts +0 -74
  55. package/dist/api-handlers/auth/refresh.js +0 -633
  56. package/dist/api-handlers/auth/signout.d.ts +0 -37
  57. package/dist/api-handlers/auth/signout.js +0 -186
  58. package/dist/api-handlers/auth/status.d.ts +0 -8
  59. package/dist/api-handlers/auth/status.js +0 -23
  60. package/dist/api-handlers/auth/update-session.d.ts +0 -37
  61. package/dist/api-handlers/auth/update-session.js +0 -93
  62. package/dist/api-handlers/auth/validate.d.ts +0 -6
  63. package/dist/api-handlers/auth/validate.js +0 -43
  64. package/dist/api-handlers/auth/verify-code.d.ts +0 -43
  65. package/dist/api-handlers/auth/verify-code.js +0 -90
  66. package/dist/api-handlers/session/refresh-viability.d.ts +0 -14
  67. package/dist/api-handlers/session/refresh-viability.js +0 -39
  68. package/dist/api-handlers/session/viability.d.ts +0 -13
  69. package/dist/api-handlers/session/viability.js +0 -114
  70. package/dist/api-handlers/test/force-expire.d.ts +0 -23
  71. package/dist/api-handlers/test/force-expire.js +0 -59
  72. package/dist/auth/auth-decision.d.ts +0 -39
  73. package/dist/auth/auth-decision.js +0 -182
  74. package/dist/auth/auth-options.d.ts +0 -57
  75. package/dist/auth/auth-options.js +0 -213
  76. package/dist/auth/better-auth.d.ts +0 -79
  77. package/dist/auth/better-auth.js +0 -119
  78. package/dist/auth/callbacks/index.d.ts +0 -6
  79. package/dist/auth/callbacks/index.js +0 -12
  80. package/dist/auth/callbacks/jwt.d.ts +0 -45
  81. package/dist/auth/callbacks/jwt.js +0 -305
  82. package/dist/auth/callbacks/session.d.ts +0 -60
  83. package/dist/auth/callbacks/session.js +0 -170
  84. package/dist/auth/callbacks/signin.d.ts +0 -23
  85. package/dist/auth/callbacks/signin.js +0 -44
  86. package/dist/auth/events/index.d.ts +0 -4
  87. package/dist/auth/events/index.js +0 -8
  88. package/dist/auth/events/signout.d.ts +0 -17
  89. package/dist/auth/events/signout.js +0 -32
  90. package/dist/auth/providers/credentials.d.ts +0 -32
  91. package/dist/auth/providers/credentials.js +0 -223
  92. package/dist/auth/providers/index.d.ts +0 -5
  93. package/dist/auth/providers/index.js +0 -21
  94. package/dist/auth/providers/oauth.d.ts +0 -26
  95. package/dist/auth/providers/oauth.js +0 -105
  96. package/dist/auth/route-config.d.ts +0 -66
  97. package/dist/auth/route-config.js +0 -190
  98. package/dist/auth/types/auth-types.d.ts +0 -417
  99. package/dist/auth/types/auth-types.js +0 -53
  100. package/dist/auth/types/index.d.ts +0 -6
  101. package/dist/auth/types/index.js +0 -22
  102. package/dist/auth/unauthenticated-routes.d.ts +0 -1
  103. package/dist/auth/unauthenticated-routes.js +0 -19
  104. package/dist/auth/utils/idp-client.d.ts +0 -94
  105. package/dist/auth/utils/idp-client.js +0 -384
  106. package/dist/auth/utils/index.d.ts +0 -5
  107. package/dist/auth/utils/index.js +0 -21
  108. package/dist/auth/utils/token-utils.d.ts +0 -83
  109. package/dist/auth/utils/token-utils.js +0 -218
  110. package/dist/client/AuthContext.d.ts +0 -19
  111. package/dist/client/AuthContext.js +0 -115
  112. package/dist/client/better-auth-client.d.ts +0 -1020
  113. package/dist/client/better-auth-client.js +0 -68
  114. package/dist/client/fetch-with-auth.d.ts +0 -11
  115. package/dist/client/fetch-with-auth.js +0 -44
  116. package/dist/client/fetchWithSession.d.ts +0 -3
  117. package/dist/client/fetchWithSession.js +0 -24
  118. package/dist/client/index.d.ts +0 -9
  119. package/dist/client/index.js +0 -20
  120. package/dist/client/useAnonSession.d.ts +0 -36
  121. package/dist/client/useAnonSession.js +0 -99
  122. package/dist/components/SessionSync.d.ts +0 -13
  123. package/dist/components/SessionSync.js +0 -121
  124. package/dist/components/SignalRHealthCheck.d.ts +0 -10
  125. package/dist/components/SignalRHealthCheck.js +0 -97
  126. package/dist/components/account/MobileNavDrawer.d.ts +0 -32
  127. package/dist/components/account/MobileNavDrawer.js +0 -81
  128. package/dist/components/account/UserAvatarMenu.d.ts +0 -20
  129. package/dist/components/account/UserAvatarMenu.js +0 -91
  130. package/dist/components/account/index.d.ts +0 -9
  131. package/dist/components/account/index.js +0 -13
  132. package/dist/components/admin/AlertSettingsTab.d.ts +0 -48
  133. package/dist/components/admin/AlertSettingsTab.js +0 -351
  134. package/dist/components/admin/AnalyticsTab.d.ts +0 -22
  135. package/dist/components/admin/AnalyticsTab.js +0 -167
  136. package/dist/components/admin/DataBrowserTab.d.ts +0 -19
  137. package/dist/components/admin/DataBrowserTab.js +0 -252
  138. package/dist/components/admin/LoggingSettingsTab.d.ts +0 -73
  139. package/dist/components/admin/LoggingSettingsTab.js +0 -339
  140. package/dist/components/admin/SessionsTab.d.ts +0 -37
  141. package/dist/components/admin/SessionsTab.js +0 -165
  142. package/dist/components/admin/StatsTab.d.ts +0 -53
  143. package/dist/components/admin/StatsTab.js +0 -161
  144. package/dist/components/admin/VibeAdminContext.d.ts +0 -32
  145. package/dist/components/admin/VibeAdminContext.js +0 -38
  146. package/dist/components/admin/VibeAdminLayout.d.ts +0 -11
  147. package/dist/components/admin/VibeAdminLayout.js +0 -71
  148. package/dist/components/admin/index.d.ts +0 -29
  149. package/dist/components/admin/index.js +0 -44
  150. package/dist/components/auth/FederatedAuthSection.d.ts +0 -8
  151. package/dist/components/auth/FederatedAuthSection.js +0 -45
  152. package/dist/components/auth/ModeAwareLoginPage.d.ts +0 -10
  153. package/dist/components/auth/ModeAwareLoginPage.js +0 -42
  154. package/dist/components/auth/ModeAwareSignupPage.d.ts +0 -9
  155. package/dist/components/auth/ModeAwareSignupPage.js +0 -78
  156. package/dist/components/auth/TraditionalAuthSection.d.ts +0 -14
  157. package/dist/components/auth/TraditionalAuthSection.js +0 -20
  158. package/dist/components/recovery/CompleteStep.d.ts +0 -5
  159. package/dist/components/recovery/CompleteStep.js +0 -8
  160. package/dist/components/recovery/InitiateRecoveryStep.d.ts +0 -8
  161. package/dist/components/recovery/InitiateRecoveryStep.js +0 -20
  162. package/dist/components/recovery/SelectMethodStep.d.ts +0 -8
  163. package/dist/components/recovery/SelectMethodStep.js +0 -8
  164. package/dist/components/recovery/SetPasswordStep.d.ts +0 -6
  165. package/dist/components/recovery/SetPasswordStep.js +0 -20
  166. package/dist/components/recovery/VerifyCodeStep.d.ts +0 -10
  167. package/dist/components/recovery/VerifyCodeStep.js +0 -24
  168. package/dist/components/reserved/ReservedRecoveryWarning.d.ts +0 -38
  169. package/dist/components/reserved/ReservedRecoveryWarning.js +0 -92
  170. package/dist/components/reserved/ReservedStatusBox.d.ts +0 -30
  171. package/dist/components/reserved/ReservedStatusBox.js +0 -71
  172. package/dist/components/ui/BetaBadge.d.ts +0 -29
  173. package/dist/components/ui/BetaBadge.js +0 -38
  174. package/dist/components/ui/Footer.d.ts +0 -37
  175. package/dist/components/ui/Footer.js +0 -41
  176. package/dist/config/env.d.ts +0 -66
  177. package/dist/config/env.js +0 -57
  178. package/dist/config/logger.d.ts +0 -57
  179. package/dist/config/logger.js +0 -73
  180. package/dist/config/logging-config.d.ts +0 -30
  181. package/dist/config/logging-config.js +0 -122
  182. package/dist/config/unauthenticated-routes.d.ts +0 -17
  183. package/dist/config/unauthenticated-routes.js +0 -24
  184. package/dist/config/vibe-log-transport.d.ts +0 -81
  185. package/dist/config/vibe-log-transport.js +0 -212
  186. package/dist/edge/internal-api-url.d.ts +0 -53
  187. package/dist/edge/internal-api-url.js +0 -63
  188. package/dist/edge/middleware.d.ts +0 -14
  189. package/dist/edge/middleware.js +0 -32
  190. package/dist/hooks/useAuth.d.ts +0 -23
  191. package/dist/hooks/useAuth.js +0 -83
  192. package/dist/hooks/useAuthSettings.d.ts +0 -59
  193. package/dist/hooks/useAuthSettings.js +0 -93
  194. package/dist/hooks/useAvailableProviders.d.ts +0 -43
  195. package/dist/hooks/useAvailableProviders.js +0 -112
  196. package/dist/hooks/usePasswordValidation.d.ts +0 -27
  197. package/dist/hooks/usePasswordValidation.js +0 -102
  198. package/dist/hooks/useProfile.d.ts +0 -15
  199. package/dist/hooks/useProfile.js +0 -59
  200. package/dist/hooks/usePublicAuthSettings.d.ts +0 -56
  201. package/dist/hooks/usePublicAuthSettings.js +0 -131
  202. package/dist/hooks/useSessionExpiration.d.ts +0 -56
  203. package/dist/hooks/useSessionExpiration.js +0 -72
  204. package/dist/hooks/useViabilitySession.d.ts +0 -75
  205. package/dist/hooks/useViabilitySession.js +0 -269
  206. package/dist/index.d.ts +0 -12
  207. package/dist/index.js +0 -53
  208. package/dist/lib/anon-session.d.ts +0 -74
  209. package/dist/lib/anon-session.js +0 -169
  210. package/dist/lib/api-handler.d.ts +0 -123
  211. package/dist/lib/api-handler.js +0 -478
  212. package/dist/lib/app-slug.d.ts +0 -95
  213. package/dist/lib/app-slug.js +0 -172
  214. package/dist/lib/demo-mode.d.ts +0 -6
  215. package/dist/lib/demo-mode.js +0 -16
  216. package/dist/lib/geolocation.d.ts +0 -64
  217. package/dist/lib/geolocation.js +0 -235
  218. package/dist/lib/idp-client-config.d.ts +0 -75
  219. package/dist/lib/idp-client-config.js +0 -425
  220. package/dist/lib/idp-fetch.d.ts +0 -14
  221. package/dist/lib/idp-fetch.js +0 -91
  222. package/dist/lib/internal-api.d.ts +0 -87
  223. package/dist/lib/internal-api.js +0 -122
  224. package/dist/lib/jwt-decode-client.d.ts +0 -10
  225. package/dist/lib/jwt-decode-client.js +0 -46
  226. package/dist/lib/jwt-decode.d.ts +0 -48
  227. package/dist/lib/jwt-decode.js +0 -57
  228. package/dist/lib/nextauth-secret.d.ts +0 -10
  229. package/dist/lib/nextauth-secret.js +0 -100
  230. package/dist/lib/rate-limit-service.d.ts +0 -23
  231. package/dist/lib/rate-limit-service.js +0 -6
  232. package/dist/lib/redis.d.ts +0 -5
  233. package/dist/lib/redis.js +0 -28
  234. package/dist/lib/refresh-token-validator.d.ts +0 -13
  235. package/dist/lib/refresh-token-validator.js +0 -117
  236. package/dist/lib/roles.d.ts +0 -145
  237. package/dist/lib/roles.js +0 -168
  238. package/dist/lib/secret-validation.d.ts +0 -4
  239. package/dist/lib/secret-validation.js +0 -14
  240. package/dist/lib/session-store.d.ts +0 -170
  241. package/dist/lib/session-store.js +0 -545
  242. package/dist/lib/session.d.ts +0 -21
  243. package/dist/lib/session.js +0 -26
  244. package/dist/lib/site-logger.d.ts +0 -214
  245. package/dist/lib/site-logger.js +0 -210
  246. package/dist/lib/standardized-client-api.d.ts +0 -161
  247. package/dist/lib/standardized-client-api.js +0 -791
  248. package/dist/lib/startup-init.d.ts +0 -40
  249. package/dist/lib/startup-init.js +0 -257
  250. package/dist/lib/test-aware-get-token.d.ts +0 -2
  251. package/dist/lib/test-aware-get-token.js +0 -86
  252. package/dist/lib/token-expiry.d.ts +0 -14
  253. package/dist/lib/token-expiry.js +0 -39
  254. package/dist/lib/token-lifecycle.d.ts +0 -78
  255. package/dist/lib/token-lifecycle.js +0 -360
  256. package/dist/lib/types/api-responses.d.ts +0 -128
  257. package/dist/lib/types/api-responses.js +0 -171
  258. package/dist/lib/user-agent-parser.d.ts +0 -50
  259. package/dist/lib/user-agent-parser.js +0 -220
  260. package/dist/logging/api/admin-analytics.d.ts +0 -3
  261. package/dist/logging/api/admin-analytics.js +0 -45
  262. package/dist/logging/api/audit-log.d.ts +0 -3
  263. package/dist/logging/api/audit-log.js +0 -52
  264. package/dist/logging/components/AdminAnalyticsLayout.d.ts +0 -10
  265. package/dist/logging/components/AdminAnalyticsLayout.js +0 -11
  266. package/dist/logging/components/AuditLogViewer.d.ts +0 -7
  267. package/dist/logging/components/AuditLogViewer.js +0 -51
  268. package/dist/logging/components/ErrorMetricsCard.d.ts +0 -7
  269. package/dist/logging/components/ErrorMetricsCard.js +0 -16
  270. package/dist/logging/components/HealthMetricsCard.d.ts +0 -7
  271. package/dist/logging/components/HealthMetricsCard.js +0 -19
  272. package/dist/logging/hooks/useAdminAnalytics.d.ts +0 -24
  273. package/dist/logging/hooks/useAdminAnalytics.js +0 -22
  274. package/dist/logging/hooks/useAuditLog.d.ts +0 -6
  275. package/dist/logging/hooks/useAuditLog.js +0 -25
  276. package/dist/logging/hooks/useErrorMetrics.d.ts +0 -6
  277. package/dist/logging/hooks/useErrorMetrics.js +0 -38
  278. package/dist/logging/hooks/useHealthMetrics.d.ts +0 -6
  279. package/dist/logging/hooks/useHealthMetrics.js +0 -41
  280. package/dist/logging/index.d.ts +0 -11
  281. package/dist/logging/index.js +0 -40
  282. package/dist/logging/types/analytics.d.ts +0 -68
  283. package/dist/logging/types/analytics.js +0 -3
  284. package/dist/logging/types/audit.d.ts +0 -29
  285. package/dist/logging/types/audit.js +0 -2
  286. package/dist/logging/types/index.d.ts +0 -2
  287. package/dist/logging/types/index.js +0 -19
  288. package/dist/middleware/auth-decision.d.ts +0 -33
  289. package/dist/middleware/auth-decision.js +0 -65
  290. package/dist/middleware/create-middleware.d.ts +0 -102
  291. package/dist/middleware/create-middleware.js +0 -469
  292. package/dist/middleware/rbac-check.d.ts +0 -51
  293. package/dist/middleware/rbac-check.js +0 -219
  294. package/dist/middleware/twofa-presets.d.ts +0 -134
  295. package/dist/middleware/twofa-presets.js +0 -175
  296. package/dist/models/DecodedAccessToken.d.ts +0 -17
  297. package/dist/models/DecodedAccessToken.js +0 -2
  298. package/dist/models/SessionModel.d.ts +0 -122
  299. package/dist/models/SessionModel.js +0 -136
  300. package/dist/pages/admin-login/page.d.ts +0 -31
  301. package/dist/pages/admin-login/page.js +0 -73
  302. package/dist/pages/admin-page-permissions/PagePermissionsAdminPage.d.ts +0 -18
  303. package/dist/pages/admin-page-permissions/PagePermissionsAdminPage.js +0 -276
  304. package/dist/pages/admin-page-permissions/index.d.ts +0 -6
  305. package/dist/pages/admin-page-permissions/index.js +0 -13
  306. package/dist/pages/admin-roles/RolesAdminPage.d.ts +0 -16
  307. package/dist/pages/admin-roles/RolesAdminPage.js +0 -261
  308. package/dist/pages/admin-roles/index.d.ts +0 -8
  309. package/dist/pages/admin-roles/index.js +0 -15
  310. package/dist/pages/admin-roles/modals.d.ts +0 -72
  311. package/dist/pages/admin-roles/modals.js +0 -154
  312. package/dist/pages/client-admin/ClientSiteAdminPage.d.ts +0 -79
  313. package/dist/pages/client-admin/ClientSiteAdminPage.js +0 -179
  314. package/dist/pages/client-admin/index.d.ts +0 -32
  315. package/dist/pages/client-admin/index.js +0 -37
  316. package/dist/pages/coming-soon/page.d.ts +0 -8
  317. package/dist/pages/coming-soon/page.js +0 -28
  318. package/dist/pages/login/page.d.ts +0 -22
  319. package/dist/pages/login/page.js +0 -230
  320. package/dist/pages/profile/EnhancedProfilePage.d.ts +0 -13
  321. package/dist/pages/profile/EnhancedProfilePage.js +0 -150
  322. package/dist/pages/profile/index.d.ts +0 -8
  323. package/dist/pages/profile/index.js +0 -16
  324. package/dist/pages/profile/page.d.ts +0 -19
  325. package/dist/pages/profile/page.js +0 -47
  326. package/dist/pages/profile/profile-patch.d.ts +0 -1
  327. package/dist/pages/profile/profile-patch.js +0 -281
  328. package/dist/pages/recovery/page.d.ts +0 -1
  329. package/dist/pages/recovery/page.js +0 -142
  330. package/dist/pages/roles/MyRolesPage.d.ts +0 -24
  331. package/dist/pages/roles/MyRolesPage.js +0 -71
  332. package/dist/pages/roles/components.d.ts +0 -63
  333. package/dist/pages/roles/components.js +0 -108
  334. package/dist/pages/roles/index.d.ts +0 -8
  335. package/dist/pages/roles/index.js +0 -19
  336. package/dist/pages/security/EnhancedSecurityPage.d.ts +0 -14
  337. package/dist/pages/security/EnhancedSecurityPage.js +0 -248
  338. package/dist/pages/security/index.d.ts +0 -8
  339. package/dist/pages/security/index.js +0 -16
  340. package/dist/pages/security/page.d.ts +0 -21
  341. package/dist/pages/security/page.js +0 -212
  342. package/dist/pages/security/security-patch.d.ts +0 -1
  343. package/dist/pages/security/security-patch.js +0 -302
  344. package/dist/pages/settings/EnhancedSettingsPage.d.ts +0 -46
  345. package/dist/pages/settings/EnhancedSettingsPage.js +0 -231
  346. package/dist/pages/settings/index.d.ts +0 -8
  347. package/dist/pages/settings/index.js +0 -16
  348. package/dist/pages/settings/page.d.ts +0 -7
  349. package/dist/pages/settings/page.js +0 -26
  350. package/dist/pages/showcase/ShowcasePage.d.ts +0 -13
  351. package/dist/pages/showcase/ShowcasePage.js +0 -142
  352. package/dist/pages/showcase/index.d.ts +0 -12
  353. package/dist/pages/showcase/index.js +0 -17
  354. package/dist/pages/test-env/EmergencyLogoutPage.d.ts +0 -14
  355. package/dist/pages/test-env/EmergencyLogoutPage.js +0 -99
  356. package/dist/pages/test-env/JwtInspectPage.d.ts +0 -14
  357. package/dist/pages/test-env/JwtInspectPage.js +0 -116
  358. package/dist/pages/test-env/RefreshTokenPage.d.ts +0 -15
  359. package/dist/pages/test-env/RefreshTokenPage.js +0 -93
  360. package/dist/pages/test-env/TestEnvPage.d.ts +0 -13
  361. package/dist/pages/test-env/TestEnvPage.js +0 -51
  362. package/dist/pages/test-env/index.d.ts +0 -24
  363. package/dist/pages/test-env/index.js +0 -32
  364. package/dist/pages/verify-code/page.d.ts +0 -30
  365. package/dist/pages/verify-code/page.js +0 -412
  366. package/dist/routes/account/index.d.ts +0 -28
  367. package/dist/routes/account/index.js +0 -71
  368. package/dist/routes/account/masked-info.d.ts +0 -33
  369. package/dist/routes/account/masked-info.js +0 -39
  370. package/dist/routes/account/send-code.d.ts +0 -37
  371. package/dist/routes/account/send-code.js +0 -42
  372. package/dist/routes/account/update-phone.d.ts +0 -13
  373. package/dist/routes/account/update-phone.js +0 -17
  374. package/dist/routes/account/verify-email.d.ts +0 -38
  375. package/dist/routes/account/verify-email.js +0 -43
  376. package/dist/routes/account/verify-sms.d.ts +0 -38
  377. package/dist/routes/account/verify-sms.js +0 -43
  378. package/dist/routes/auth/index.d.ts +0 -19
  379. package/dist/routes/auth/index.js +0 -64
  380. package/dist/routes/auth/logout.d.ts +0 -31
  381. package/dist/routes/auth/logout.js +0 -98
  382. package/dist/routes/auth/nextauth.d.ts +0 -22
  383. package/dist/routes/auth/nextauth.js +0 -40
  384. package/dist/routes/auth/refresh.d.ts +0 -30
  385. package/dist/routes/auth/refresh.js +0 -51
  386. package/dist/routes/auth/session.d.ts +0 -43
  387. package/dist/routes/auth/session.js +0 -157
  388. package/dist/routes/auth/settings.d.ts +0 -25
  389. package/dist/routes/auth/settings.js +0 -55
  390. package/dist/routes/auth/viability.d.ts +0 -52
  391. package/dist/routes/auth/viability.js +0 -190
  392. package/dist/routes/index.d.ts +0 -12
  393. package/dist/routes/index.js +0 -54
  394. package/dist/routes/session/index.d.ts +0 -6
  395. package/dist/routes/session/index.js +0 -10
  396. package/dist/routes/session/refresh-viability.d.ts +0 -16
  397. package/dist/routes/session/refresh-viability.js +0 -20
  398. package/dist/server/auth-guard.d.ts +0 -46
  399. package/dist/server/auth-guard.js +0 -128
  400. package/dist/server/auth.d.ts +0 -50
  401. package/dist/server/auth.js +0 -62
  402. package/dist/server/decode-session.d.ts +0 -30
  403. package/dist/server/decode-session.js +0 -78
  404. package/dist/server/slim-middleware.d.ts +0 -23
  405. package/dist/server/slim-middleware.js +0 -89
  406. package/dist/server/with-auth.d.ts +0 -33
  407. package/dist/server/with-auth.js +0 -59
  408. package/dist/services/signalrActivityService.d.ts +0 -44
  409. package/dist/services/signalrActivityService.js +0 -257
  410. package/dist/stores/authStore.d.ts +0 -154
  411. package/dist/stores/authStore.js +0 -1527
  412. package/dist/theme/ThemeProvider.d.ts +0 -14
  413. package/dist/theme/ThemeProvider.js +0 -28
  414. package/dist/theme/default.d.ts +0 -8
  415. package/dist/theme/default.js +0 -33
  416. package/dist/theme/index.d.ts +0 -15
  417. package/dist/theme/index.js +0 -25
  418. package/dist/theme/types.d.ts +0 -56
  419. package/dist/theme/types.js +0 -8
  420. package/dist/theme/useTheme.d.ts +0 -60
  421. package/dist/theme/useTheme.js +0 -63
  422. package/dist/theme/utils.d.ts +0 -13
  423. package/dist/theme/utils.js +0 -39
  424. package/dist/types/api.d.ts +0 -134
  425. package/dist/types/api.js +0 -44
  426. package/dist/types/auth.d.ts +0 -19
  427. package/dist/types/auth.js +0 -2
  428. package/dist/types/logging.d.ts +0 -42
  429. package/dist/types/logging.js +0 -2
  430. package/dist/types/recovery.d.ts +0 -48
  431. package/dist/types/recovery.js +0 -2
  432. package/dist/types/security.d.ts +0 -1
  433. package/dist/types/security.js +0 -2
  434. package/dist/utils/api.d.ts +0 -85
  435. package/dist/utils/api.js +0 -287
  436. package/dist/utils/circuitBreaker.d.ts +0 -43
  437. package/dist/utils/circuitBreaker.js +0 -91
  438. package/dist/utils/error-message.d.ts +0 -1
  439. package/dist/utils/error-message.js +0 -103
  440. package/dist/utils/layout/reservedSpace.d.ts +0 -59
  441. package/dist/utils/layout/reservedSpace.js +0 -102
  442. package/dist/utils/logout.d.ts +0 -14
  443. package/dist/utils/logout.js +0 -32
  444. package/dist/vibe/client.d.ts +0 -261
  445. package/dist/vibe/client.js +0 -445
  446. package/dist/vibe/enterprise-auth.d.ts +0 -106
  447. package/dist/vibe/enterprise-auth.js +0 -173
  448. package/dist/vibe/errors.d.ts +0 -83
  449. package/dist/vibe/errors.js +0 -146
  450. package/dist/vibe/generic.d.ts +0 -234
  451. package/dist/vibe/generic.js +0 -369
  452. package/dist/vibe/hooks/index.d.ts +0 -169
  453. package/dist/vibe/hooks/index.js +0 -252
  454. package/dist/vibe/index.d.ts +0 -25
  455. package/dist/vibe/index.js +0 -72
  456. package/dist/vibe/sessions.d.ts +0 -161
  457. package/dist/vibe/sessions.js +0 -391
  458. package/dist/vibe/types.d.ts +0 -353
  459. package/dist/vibe/types.js +0 -315
@@ -1,81 +0,0 @@
1
- "use strict";
2
- 'use client';
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.MobileNavDrawer = MobileNavDrawer;
8
- const jsx_runtime_1 = require("react/jsx-runtime");
9
- const react_1 = require("react");
10
- const better_auth_client_1 = require("../../client/better-auth-client");
11
- const navigation_1 = require("next/navigation");
12
- const image_1 = __importDefault(require("next/image"));
13
- const link_1 = __importDefault(require("next/link"));
14
- const lucide_react_1 = require("lucide-react");
15
- function MobileNavDrawer({ isOpen, onClose, navItems, customSections, basePath = '/account', onSignIn, signInCallbackUrl = '/dashboard', unauthActions, authFooter, }) {
16
- const { data: session } = better_auth_client_1.authClient.useSession();
17
- const pathname = (0, navigation_1.usePathname)();
18
- const isAuthenticated = !!session?.user;
19
- const isActiveRoute = (0, react_1.useCallback)((href) => pathname?.startsWith(href) ?? false, [pathname]);
20
- // Close on Escape key
21
- (0, react_1.useEffect)(() => {
22
- function handleEscape(event) {
23
- if (event.key === 'Escape') {
24
- onClose();
25
- }
26
- }
27
- if (isOpen) {
28
- document.addEventListener('keydown', handleEscape);
29
- return () => document.removeEventListener('keydown', handleEscape);
30
- }
31
- }, [isOpen, onClose]);
32
- // Lock body scroll when open
33
- (0, react_1.useEffect)(() => {
34
- if (isOpen) {
35
- document.body.style.overflow = 'hidden';
36
- return () => {
37
- document.body.style.overflow = '';
38
- };
39
- }
40
- }, [isOpen]);
41
- const handleSignIn = () => {
42
- onClose();
43
- if (onSignIn) {
44
- onSignIn();
45
- }
46
- else {
47
- better_auth_client_1.authClient.signIn.social({ provider: 'google', callbackURL: signInCallbackUrl });
48
- }
49
- };
50
- const handleSectionItemClick = (item) => {
51
- onClose();
52
- if (item.onClick) {
53
- item.onClick();
54
- }
55
- };
56
- // Derive display initial from name or email
57
- const userName = session?.user?.name;
58
- const userEmail = session?.user?.email;
59
- const displaySource = userName || userEmail;
60
- const userInitial = displaySource?.charAt(0).toUpperCase() || '?';
61
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: `
62
- fixed inset-0 bg-black/50 backdrop-blur-sm z-40 lg:hidden
63
- transition-opacity duration-300
64
- ${isOpen ? 'opacity-100' : 'opacity-0 pointer-events-none'}
65
- `, onClick: onClose, "aria-hidden": "true" }), (0, jsx_runtime_1.jsxs)("div", { role: "dialog", "aria-modal": "true", "aria-label": "Navigation menu", "aria-expanded": isOpen, className: `
66
- fixed top-0 right-0 bottom-0 w-80 max-w-[85vw]
67
- bg-white dark:bg-slate-900
68
- shadow-[-8px_0_32px_rgba(0,0,0,0.15)]
69
- dark:shadow-[-8px_0_32px_rgba(0,0,0,0.4)]
70
- z-50 lg:hidden
71
- overflow-y-auto
72
- transition-transform duration-300 ease-out
73
- ${isOpen ? 'translate-x-0' : 'translate-x-full'}
74
- `, children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between p-4 border-b border-gray-200 dark:border-white/10", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: "Menu" }), (0, jsx_runtime_1.jsx)("button", { onClick: onClose, className: "\r\n p-2 rounded-xl\r\n text-gray-400 hover:text-gray-900\r\n dark:hover:text-white\r\n hover:bg-gray-100 dark:hover:bg-white/10\r\n transition-colors\r\n ", "aria-label": "Close menu", children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { className: "h-5 w-5" }) })] }), isAuthenticated && session?.user && ((0, jsx_runtime_1.jsx)("div", { className: "p-4 border-b border-gray-200 dark:border-white/10", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [session.user.image ? ((0, jsx_runtime_1.jsx)(image_1.default, { src: session.user.image, alt: "", width: 48, height: 48, className: "w-12 h-12 rounded-full", unoptimized: true })) : ((0, jsx_runtime_1.jsx)("div", { className: "w-12 h-12 rounded-full bg-blue-500 flex items-center justify-center text-white font-semibold text-lg", children: userInitial })), (0, jsx_runtime_1.jsxs)("div", { className: "flex-1 min-w-0", children: [userName && ((0, jsx_runtime_1.jsx)("p", { className: "text-sm font-semibold text-gray-900 dark:text-white truncate", children: userName })), userEmail && ((0, jsx_runtime_1.jsx)("p", { className: "text-xs text-gray-500 dark:text-slate-400 truncate", children: userEmail }))] })] }) })), (0, jsx_runtime_1.jsx)("div", { className: "p-2", children: navItems.map((item) => ((0, jsx_runtime_1.jsxs)(link_1.default, { href: item.href, onClick: onClose, className: `
75
- flex items-center gap-3 px-4 py-3.5 rounded-xl
76
- transition-colors duration-200
77
- ${isActiveRoute(item.href)
78
- ? 'bg-blue-500/10 text-blue-500'
79
- : 'text-gray-900 dark:text-white hover:bg-gray-100 dark:hover:bg-white/10'}
80
- `, children: [item.icon && (0, jsx_runtime_1.jsx)("span", { className: "text-xl", children: item.icon }), (0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: item.label }), isActiveRoute(item.href) && ((0, jsx_runtime_1.jsx)("span", { className: "ml-auto w-2 h-2 rounded-full bg-blue-500" }))] }, item.href))) }), customSections?.map((section, sectionIndex) => ((0, jsx_runtime_1.jsxs)("div", { className: "p-2 border-t border-gray-200 dark:border-white/10", children: [section.title && ((0, jsx_runtime_1.jsx)("p", { className: "px-4 py-2 text-xs font-semibold text-gray-500 dark:text-slate-400 uppercase tracking-wider", children: section.title })), section.items.map((item, itemIndex) => item.href ? ((0, jsx_runtime_1.jsxs)(link_1.default, { href: item.href, onClick: onClose, className: "\r\n flex items-center gap-3 px-4 py-3 rounded-xl\r\n text-gray-900 dark:text-white\r\n hover:bg-gray-100 dark:hover:bg-white/10\r\n transition-colors\r\n ", children: [item.icon && (0, jsx_runtime_1.jsx)("span", { className: "text-xl", children: item.icon }), (0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: item.label })] }, itemIndex)) : ((0, jsx_runtime_1.jsxs)("button", { onClick: () => handleSectionItemClick(item), className: "\r\n flex items-center gap-3 px-4 py-3 rounded-xl w-full text-left\r\n text-gray-900 dark:text-white\r\n hover:bg-gray-100 dark:hover:bg-white/10\r\n transition-colors\r\n ", children: [item.icon && (0, jsx_runtime_1.jsx)("span", { className: "text-xl", children: item.icon }), (0, jsx_runtime_1.jsx)("span", { className: "font-medium", children: item.label })] }, itemIndex)))] }, sectionIndex))), (0, jsx_runtime_1.jsx)("div", { className: "p-4 mt-auto border-t border-gray-200 dark:border-white/10", children: !isAuthenticated ? (unauthActions ?? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: (0, jsx_runtime_1.jsx)("button", { onClick: handleSignIn, className: "\r\n w-full px-4 py-3 rounded-xl\r\n text-blue-500 font-semibold\r\n border border-blue-500/30\r\n hover:bg-blue-500/10\r\n transition-colors\r\n ", children: "Login" }) }))) : (authFooter ?? ((0, jsx_runtime_1.jsx)(link_1.default, { href: basePath, onClick: onClose, className: "\r\n flex items-center justify-center gap-2\r\n w-full px-4 py-3 rounded-xl\r\n text-gray-500 dark:text-slate-400 font-medium\r\n hover:bg-gray-100 dark:hover:bg-white/10\r\n transition-colors\r\n ", children: "Account Settings" }))) })] })] }));
81
- }
@@ -1,20 +0,0 @@
1
- export interface UserAvatarMenuProps {
2
- /** Base path for navigation (e.g., '/dashboard', '/account') */
3
- basePath?: string;
4
- /** Show Profile menu item (default: true) */
5
- showProfile?: boolean;
6
- /** Show Settings menu item (default: true) */
7
- showSettings?: boolean;
8
- /** Show Security menu item (default: true) */
9
- showSecurity?: boolean;
10
- /** Custom menu items to add before the sign out divider */
11
- customItems?: Array<{
12
- label: string;
13
- icon?: React.ReactNode;
14
- href?: string;
15
- onClick?: () => void;
16
- }>;
17
- /** Override default signOut behavior */
18
- onSignOut?: () => void;
19
- }
20
- export declare function UserAvatarMenu({ basePath, showProfile, showSettings, showSecurity, customItems, onSignOut, }: UserAvatarMenuProps): import("react/jsx-runtime").JSX.Element | null;
@@ -1,91 +0,0 @@
1
- "use strict";
2
- 'use client';
3
- var __importDefault = (this && this.__importDefault) || function (mod) {
4
- return (mod && mod.__esModule) ? mod : { "default": mod };
5
- };
6
- Object.defineProperty(exports, "__esModule", { value: true });
7
- exports.UserAvatarMenu = UserAvatarMenu;
8
- const jsx_runtime_1 = require("react/jsx-runtime");
9
- const react_1 = require("react");
10
- const better_auth_client_1 = require("../../client/better-auth-client");
11
- const navigation_1 = require("next/navigation");
12
- const image_1 = __importDefault(require("next/image"));
13
- const lucide_react_1 = require("lucide-react");
14
- function UserAvatarMenu({ basePath = '', showProfile = true, showSettings = true, showSecurity = true, customItems, onSignOut, }) {
15
- const { data: sessionData, isPending } = better_auth_client_1.authClient.useSession();
16
- const session = sessionData;
17
- const status = isPending ? 'loading' : session ? 'authenticated' : 'unauthenticated';
18
- const router = (0, navigation_1.useRouter)();
19
- const [isOpen, setIsOpen] = (0, react_1.useState)(false);
20
- const menuRef = (0, react_1.useRef)(null);
21
- // Close menu when clicking outside
22
- (0, react_1.useEffect)(() => {
23
- function handleClickOutside(event) {
24
- if (menuRef.current && !menuRef.current.contains(event.target)) {
25
- setIsOpen(false);
26
- }
27
- }
28
- if (isOpen) {
29
- document.addEventListener('mousedown', handleClickOutside);
30
- return () => document.removeEventListener('mousedown', handleClickOutside);
31
- }
32
- }, [isOpen]);
33
- // Close menu on Escape
34
- (0, react_1.useEffect)(() => {
35
- function handleEscape(event) {
36
- if (event.key === 'Escape') {
37
- setIsOpen(false);
38
- }
39
- }
40
- if (isOpen) {
41
- document.addEventListener('keydown', handleEscape);
42
- return () => document.removeEventListener('keydown', handleEscape);
43
- }
44
- }, [isOpen]);
45
- // Loading state
46
- if (status === 'loading') {
47
- return ((0, jsx_runtime_1.jsx)("div", { className: "h-10 w-10 rounded-full bg-gray-200 dark:bg-white/10 animate-pulse" }));
48
- }
49
- // Not authenticated
50
- if (!session?.user) {
51
- return null;
52
- }
53
- // Derive display initial from name or email — ignore anon/internal IDs
54
- const userName = session.user?.name;
55
- const userEmail = session.user.email;
56
- const displaySource = userName || userEmail;
57
- const userInitial = displaySource?.charAt(0).toUpperCase() || '?';
58
- const handleNavigation = (path) => {
59
- setIsOpen(false);
60
- router.push(path);
61
- };
62
- const handleSignOut = async () => {
63
- setIsOpen(false);
64
- if (onSignOut) {
65
- onSignOut();
66
- }
67
- else {
68
- // Use NEXT_PUBLIC env var or default to root
69
- const logoutUrl = process.env.NEXT_PUBLIC_LOGOUT_REDIRECT_URL || '/';
70
- await better_auth_client_1.authClient.signOut();
71
- window.location.href = logoutUrl;
72
- }
73
- };
74
- const handleItemClick = (item) => {
75
- setIsOpen(false);
76
- if (item.onClick) {
77
- item.onClick();
78
- }
79
- else if (item.href) {
80
- router.push(item.href);
81
- }
82
- };
83
- return ((0, jsx_runtime_1.jsxs)("div", { ref: menuRef, className: "relative", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setIsOpen(!isOpen), className: "flex items-center justify-center h-10 w-10 rounded-full overflow-hidden bg-blue-500 text-white font-semibold text-lg hover:opacity-90 transition-opacity focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:focus:ring-offset-slate-900", "aria-label": "User menu", "aria-expanded": isOpen, "aria-haspopup": "true", children: session.user.image ? ((0, jsx_runtime_1.jsx)(image_1.default, { src: session.user.image, alt: "", width: 40, height: 40, className: "w-10 h-10 rounded-full object-cover", unoptimized: true })) : (userInitial) }), isOpen && ((0, jsx_runtime_1.jsxs)("div", { className: "absolute right-0 mt-2 w-56 rounded-md shadow-lg z-50\r\n bg-white dark:bg-slate-900\r\n border border-gray-200 dark:border-slate-700", role: "menu", "aria-orientation": "vertical", children: [(0, jsx_runtime_1.jsx)("div", { className: "px-4 py-3 border-b border-gray-200 dark:border-slate-700", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [session.user.image ? ((0, jsx_runtime_1.jsx)(image_1.default, { src: session.user.image, alt: "", width: 32, height: 32, className: "w-8 h-8 rounded-full flex-shrink-0", unoptimized: true })) : ((0, jsx_runtime_1.jsx)("div", { className: "w-8 h-8 rounded-full bg-blue-500 flex items-center justify-center text-white font-semibold text-sm flex-shrink-0", children: userInitial })), (0, jsx_runtime_1.jsxs)("div", { className: "min-w-0", children: [userName && ((0, jsx_runtime_1.jsx)("p", { className: "text-sm font-medium text-gray-700 dark:text-slate-200 truncate", children: userName })), userEmail && ((0, jsx_runtime_1.jsx)("p", { className: "text-sm text-gray-500 dark:text-slate-400 truncate", children: userEmail })), !userName && !userEmail && ((0, jsx_runtime_1.jsx)("p", { className: "text-sm text-gray-500 dark:text-slate-400", children: "Signed in" }))] })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "py-1", children: [showProfile && ((0, jsx_runtime_1.jsx)(MenuItem, { icon: (0, jsx_runtime_1.jsx)(lucide_react_1.User, { className: "h-4 w-4" }), label: "Profile", onClick: () => handleNavigation(`${basePath}/profile`) })), showSettings && ((0, jsx_runtime_1.jsx)(MenuItem, { icon: (0, jsx_runtime_1.jsx)(lucide_react_1.Settings, { className: "h-4 w-4" }), label: "Settings", onClick: () => handleNavigation(`${basePath}/settings`) })), showSecurity && ((0, jsx_runtime_1.jsx)(MenuItem, { icon: (0, jsx_runtime_1.jsx)(lucide_react_1.Shield, { className: "h-4 w-4" }), label: "Security", onClick: () => handleNavigation(`${basePath}/security`) })), customItems?.map((item, index) => ((0, jsx_runtime_1.jsx)(MenuItem, { icon: item.icon, label: item.label, onClick: () => handleItemClick(item) }, index)))] }), (0, jsx_runtime_1.jsx)("div", { className: "border-t border-gray-200 dark:border-slate-700 py-1", children: (0, jsx_runtime_1.jsx)(MenuItem, { icon: (0, jsx_runtime_1.jsx)(lucide_react_1.LogOut, { className: "h-4 w-4" }), label: "Sign Out", onClick: handleSignOut, variant: "danger" }) })] }))] }));
84
- }
85
- function MenuItem({ icon, label, onClick, variant = 'default' }) {
86
- const baseClasses = "flex items-center w-full px-4 py-2 text-sm cursor-pointer transition-colors";
87
- const variantClasses = variant === 'danger'
88
- ? "text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-slate-800"
89
- : "text-gray-700 dark:text-white hover:bg-gray-100 dark:hover:bg-slate-800";
90
- return ((0, jsx_runtime_1.jsxs)("button", { onClick: onClick, className: `${baseClasses} ${variantClasses}`, role: "menuitem", children: [icon && (0, jsx_runtime_1.jsx)("span", { className: "mr-3", children: icon }), (0, jsx_runtime_1.jsx)("span", { children: label })] }));
91
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * Account Components for @payez/next-mvp
3
- *
4
- * User account related UI components.
5
- */
6
- export { UserAvatarMenu } from './UserAvatarMenu';
7
- export type { UserAvatarMenuProps } from './UserAvatarMenu';
8
- export { MobileNavDrawer } from './MobileNavDrawer';
9
- export type { MobileNavDrawerProps, NavItem, NavSection } from './MobileNavDrawer';
@@ -1,13 +0,0 @@
1
- "use strict";
2
- 'use client';
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.MobileNavDrawer = exports.UserAvatarMenu = void 0;
5
- /**
6
- * Account Components for @payez/next-mvp
7
- *
8
- * User account related UI components.
9
- */
10
- var UserAvatarMenu_1 = require("./UserAvatarMenu");
11
- Object.defineProperty(exports, "UserAvatarMenu", { enumerable: true, get: function () { return UserAvatarMenu_1.UserAvatarMenu; } });
12
- var MobileNavDrawer_1 = require("./MobileNavDrawer");
13
- Object.defineProperty(exports, "MobileNavDrawer", { enumerable: true, get: function () { return MobileNavDrawer_1.MobileNavDrawer; } });
@@ -1,48 +0,0 @@
1
- /**
2
- * =============================================================================
3
- * VIBE ADMIN ALERT SETTINGS TAB
4
- * =============================================================================
5
- *
6
- * Admin UI for managing email alert preferences, recipients, and thresholds.
7
- * Supports Smart/Immediate/Hourly/Daily delivery modes.
8
- *
9
- * =============================================================================
10
- */
11
- export type DeliveryMode = 'smart' | 'immediate' | 'hourly' | 'daily';
12
- export interface AlertConfig {
13
- enabled: boolean;
14
- threshold?: number;
15
- threshold_pct?: number;
16
- }
17
- export interface AlertsConfig {
18
- error_spike: AlertConfig;
19
- storage_warning: AlertConfig;
20
- storage_critical: AlertConfig;
21
- agent_expiring: AlertConfig;
22
- agent_expired: AlertConfig;
23
- }
24
- export interface RateLimit {
25
- max_per_hour: number;
26
- }
27
- export interface AlertSettings {
28
- recipients: string[];
29
- digest_mode: DeliveryMode;
30
- alerts: AlertsConfig;
31
- rate_limit: RateLimit;
32
- }
33
- export interface AlertHistoryItem {
34
- id: number;
35
- type: string;
36
- sent_at: string;
37
- subject: string;
38
- recipients: string[];
39
- }
40
- export interface AlertSettingsTabProps {
41
- isDark?: boolean;
42
- /** API base path (default: /api/admin/alerts) */
43
- apiBasePath?: string;
44
- /** Callback when settings are saved */
45
- onSave?: (settings: Partial<AlertSettings>) => void;
46
- }
47
- export declare function AlertSettingsTab({ isDark, apiBasePath, onSave, }: AlertSettingsTabProps): import("react/jsx-runtime").JSX.Element;
48
- export default AlertSettingsTab;
@@ -1,351 +0,0 @@
1
- "use strict";
2
- /**
3
- * =============================================================================
4
- * VIBE ADMIN ALERT SETTINGS TAB
5
- * =============================================================================
6
- *
7
- * Admin UI for managing email alert preferences, recipients, and thresholds.
8
- * Supports Smart/Immediate/Hourly/Daily delivery modes.
9
- *
10
- * =============================================================================
11
- */
12
- 'use client';
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.AlertSettingsTab = AlertSettingsTab;
15
- const jsx_runtime_1 = require("react/jsx-runtime");
16
- const react_1 = require("react");
17
- const lucide_react_1 = require("lucide-react");
18
- // -----------------------------------------------------------------------------
19
- // CONSTANTS
20
- // -----------------------------------------------------------------------------
21
- const DELIVERY_MODES = [
22
- { value: 'smart', label: 'Smart', description: 'Critical alerts immediate, others batched (Recommended)' },
23
- { value: 'immediate', label: 'Immediate', description: 'All alerts sent as they occur' },
24
- { value: 'hourly', label: 'Hourly', description: 'Batched into hourly digest' },
25
- { value: 'daily', label: 'Daily', description: 'Batched into daily digest (8 AM)' },
26
- ];
27
- const ALERT_TYPES = [
28
- {
29
- id: 'error_spike',
30
- label: 'Error Spike',
31
- description: 'Alert when errors exceed threshold',
32
- icon: lucide_react_1.AlertTriangle,
33
- hasThreshold: true,
34
- thresholdLabel: 'Threshold',
35
- thresholdUnit: 'errors/hour',
36
- },
37
- {
38
- id: 'storage_warning',
39
- label: 'Storage Warning',
40
- description: 'Alert when log storage approaches capacity',
41
- icon: lucide_react_1.HardDrive,
42
- hasThreshold: true,
43
- thresholdLabel: 'Threshold',
44
- thresholdUnit: '% capacity',
45
- },
46
- {
47
- id: 'storage_critical',
48
- label: 'Storage Critical',
49
- description: 'Alert when storage is nearly full',
50
- icon: lucide_react_1.HardDrive,
51
- hasThreshold: true,
52
- thresholdLabel: 'Threshold',
53
- thresholdUnit: '% capacity',
54
- alwaysSent: true,
55
- },
56
- {
57
- id: 'agent_expiring',
58
- label: 'Agent Access Expiring',
59
- description: 'Alert 24 hours before agent access expires',
60
- icon: lucide_react_1.Bot,
61
- hasThreshold: false,
62
- },
63
- {
64
- id: 'agent_expired',
65
- label: 'Agent Access Expired',
66
- description: 'Alert when agent access has expired',
67
- icon: lucide_react_1.Bot,
68
- hasThreshold: false,
69
- alwaysSent: true,
70
- },
71
- ];
72
- const TEST_ALERT_OPTIONS = [
73
- { value: 'error_spike', label: 'Error Spike Alert' },
74
- { value: 'storage_warning', label: 'Storage Warning Alert' },
75
- { value: 'agent_expiring', label: 'Agent Expiring Alert' },
76
- ];
77
- const DEFAULT_SETTINGS = {
78
- recipients: [],
79
- digest_mode: 'smart',
80
- alerts: {
81
- error_spike: { enabled: true, threshold: 10 },
82
- storage_warning: { enabled: true, threshold_pct: 80 },
83
- storage_critical: { enabled: true, threshold_pct: 95 },
84
- agent_expiring: { enabled: true },
85
- agent_expired: { enabled: true },
86
- },
87
- rate_limit: { max_per_hour: 10 },
88
- };
89
- // -----------------------------------------------------------------------------
90
- // COMPONENT
91
- // -----------------------------------------------------------------------------
92
- function AlertSettingsTab({ isDark = true, apiBasePath = '/api/admin/alerts', onSave, }) {
93
- const [settings, setSettings] = (0, react_1.useState)(null);
94
- const [loading, setLoading] = (0, react_1.useState)(true);
95
- const [saving, setSaving] = (0, react_1.useState)(false);
96
- const [sendingTest, setSendingTest] = (0, react_1.useState)(false);
97
- const [error, setError] = (0, react_1.useState)(null);
98
- const [successMessage, setSuccessMessage] = (0, react_1.useState)(null);
99
- const [hasChanges, setHasChanges] = (0, react_1.useState)(false);
100
- // Edited state
101
- const [editedRecipients, setEditedRecipients] = (0, react_1.useState)([]);
102
- const [editedMode, setEditedMode] = (0, react_1.useState)('smart');
103
- const [editedAlerts, setEditedAlerts] = (0, react_1.useState)(DEFAULT_SETTINGS.alerts);
104
- const [editedRateLimit, setEditedRateLimit] = (0, react_1.useState)(10);
105
- // New recipient input
106
- const [newRecipient, setNewRecipient] = (0, react_1.useState)('');
107
- const [recipientError, setRecipientError] = (0, react_1.useState)(null);
108
- const themeClasses = {
109
- bg: isDark ? 'bg-slate-950' : 'bg-gray-50',
110
- cardBg: isDark ? 'bg-slate-800 border-slate-700' : 'bg-white border-gray-200 shadow-sm',
111
- textPrimary: isDark ? 'text-white' : 'text-gray-900',
112
- textSecondary: isDark ? 'text-gray-400' : 'text-gray-600',
113
- textMuted: isDark ? 'text-gray-500' : 'text-gray-500',
114
- inputBg: isDark ? 'bg-slate-900 border-slate-600' : 'bg-white border-gray-300',
115
- hoverBg: isDark ? 'hover:bg-slate-700' : 'hover:bg-gray-100',
116
- tagBg: isDark ? 'bg-slate-700' : 'bg-gray-100',
117
- };
118
- // Fetch settings
119
- const fetchSettings = (0, react_1.useCallback)(async () => {
120
- setLoading(true);
121
- setError(null);
122
- try {
123
- const res = await fetch(`${apiBasePath}/settings`);
124
- if (res.ok) {
125
- const data = await res.json();
126
- setSettings(data);
127
- setEditedRecipients(data.recipients || []);
128
- setEditedMode(data.digest_mode || 'smart');
129
- setEditedAlerts(data.alerts || DEFAULT_SETTINGS.alerts);
130
- setEditedRateLimit(data.rate_limit?.max_per_hour || 10);
131
- }
132
- else if (res.status === 404) {
133
- // Endpoint not ready - use defaults
134
- setSettings(DEFAULT_SETTINGS);
135
- setEditedRecipients([]);
136
- setEditedMode('smart');
137
- setEditedAlerts(DEFAULT_SETTINGS.alerts);
138
- setEditedRateLimit(10);
139
- }
140
- else {
141
- throw new Error('Failed to fetch settings');
142
- }
143
- }
144
- catch (err) {
145
- setError(err.message);
146
- }
147
- finally {
148
- setLoading(false);
149
- }
150
- }, [apiBasePath]);
151
- (0, react_1.useEffect)(() => {
152
- fetchSettings();
153
- }, [fetchSettings]);
154
- // Check for changes
155
- (0, react_1.useEffect)(() => {
156
- if (!settings) {
157
- setHasChanges(false);
158
- return;
159
- }
160
- const recipientsChanged = JSON.stringify(settings.recipients) !== JSON.stringify(editedRecipients);
161
- const modeChanged = settings.digest_mode !== editedMode;
162
- const alertsChanged = JSON.stringify(settings.alerts) !== JSON.stringify(editedAlerts);
163
- const rateLimitChanged = settings.rate_limit.max_per_hour !== editedRateLimit;
164
- setHasChanges(recipientsChanged || modeChanged || alertsChanged || rateLimitChanged);
165
- }, [settings, editedRecipients, editedMode, editedAlerts, editedRateLimit]);
166
- // Add recipient
167
- const addRecipient = () => {
168
- const email = newRecipient.trim().toLowerCase();
169
- setRecipientError(null);
170
- if (!email)
171
- return;
172
- // Basic email validation
173
- const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
174
- if (!emailRegex.test(email)) {
175
- setRecipientError('Please enter a valid email address');
176
- return;
177
- }
178
- if (editedRecipients.includes(email)) {
179
- setRecipientError('This email is already in the list');
180
- return;
181
- }
182
- setEditedRecipients([...editedRecipients, email]);
183
- setNewRecipient('');
184
- };
185
- // Remove recipient
186
- const removeRecipient = (email) => {
187
- setEditedRecipients(editedRecipients.filter(r => r !== email));
188
- };
189
- // Update alert config
190
- const updateAlertConfig = (alertId, updates) => {
191
- setEditedAlerts(prev => ({
192
- ...prev,
193
- [alertId]: { ...prev[alertId], ...updates },
194
- }));
195
- };
196
- // Save settings
197
- const saveSettings = async () => {
198
- if (!hasChanges)
199
- return;
200
- setSaving(true);
201
- setError(null);
202
- try {
203
- const payload = {
204
- recipients: editedRecipients,
205
- digest_mode: editedMode,
206
- alerts: editedAlerts,
207
- rate_limit: { max_per_hour: editedRateLimit },
208
- };
209
- const res = await fetch(`${apiBasePath}/settings`, {
210
- method: 'PUT',
211
- headers: { 'Content-Type': 'application/json' },
212
- body: JSON.stringify(payload),
213
- });
214
- if (res.ok) {
215
- setSuccessMessage('Settings saved successfully');
216
- setTimeout(() => setSuccessMessage(null), 3000);
217
- onSave?.(payload);
218
- fetchSettings();
219
- }
220
- else if (res.status === 404) {
221
- // Endpoint not ready - simulate success
222
- setSettings(payload);
223
- setSuccessMessage('Settings saved (demo mode)');
224
- setTimeout(() => setSuccessMessage(null), 3000);
225
- }
226
- else {
227
- throw new Error('Failed to save settings');
228
- }
229
- }
230
- catch (err) {
231
- setError(err.message);
232
- }
233
- finally {
234
- setSaving(false);
235
- }
236
- };
237
- // Send test alert
238
- const sendTestAlert = async (alertType) => {
239
- setSendingTest(true);
240
- setError(null);
241
- try {
242
- const res = await fetch(`${apiBasePath}/test`, {
243
- method: 'POST',
244
- headers: { 'Content-Type': 'application/json' },
245
- body: JSON.stringify({
246
- type: alertType,
247
- recipient: editedRecipients[0] || 'test@example.com',
248
- }),
249
- });
250
- if (res.ok) {
251
- setSuccessMessage(`Test ${alertType.replace('_', ' ')} alert sent!`);
252
- setTimeout(() => setSuccessMessage(null), 3000);
253
- }
254
- else if (res.status === 404) {
255
- setSuccessMessage('Test alert sent (demo mode)');
256
- setTimeout(() => setSuccessMessage(null), 3000);
257
- }
258
- else {
259
- throw new Error('Failed to send test alert');
260
- }
261
- }
262
- catch (err) {
263
- setError(err.message);
264
- }
265
- finally {
266
- setSendingTest(false);
267
- }
268
- };
269
- if (loading) {
270
- return ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-12", children: (0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCw, { className: "w-8 h-8 animate-spin text-indigo-500" }) }));
271
- }
272
- return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6", children: [error && ((0, jsx_runtime_1.jsxs)("div", { className: `flex items-center gap-3 p-4 rounded-lg ${isDark ? 'bg-red-900/30 border-red-700' : 'bg-red-50 border-red-300'} border`, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.AlertCircle, { className: isDark ? 'text-red-400' : 'text-red-500', size: 20 }), (0, jsx_runtime_1.jsx)("span", { className: isDark ? 'text-red-300' : 'text-red-700', children: error })] })), successMessage && ((0, jsx_runtime_1.jsxs)("div", { className: `flex items-center gap-3 p-4 rounded-lg ${isDark ? 'bg-green-900/30 border-green-700' : 'bg-green-50 border-green-300'} border`, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Check, { className: isDark ? 'text-green-400' : 'text-green-500', size: 20 }), (0, jsx_runtime_1.jsx)("span", { className: isDark ? 'text-green-300' : 'text-green-700', children: successMessage })] })), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-xl overflow-hidden`, children: [(0, jsx_runtime_1.jsxs)("div", { className: `px-5 py-4 border-b ${isDark ? 'border-slate-700' : 'border-gray-200'}`, children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Mail, { className: isDark ? 'text-violet-400' : 'text-violet-500', size: 20 }), (0, jsx_runtime_1.jsx)("h3", { className: `font-semibold ${themeClasses.textPrimary}`, children: "Alert Recipients" })] }), (0, jsx_runtime_1.jsx)("p", { className: `text-sm ${themeClasses.textMuted} mt-1`, children: "Email addresses that receive alert notifications" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "p-5 space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap gap-2", children: [editedRecipients.map((email) => ((0, jsx_runtime_1.jsxs)("div", { className: `flex items-center gap-2 px-3 py-1.5 rounded-lg ${themeClasses.tagBg}`, children: [(0, jsx_runtime_1.jsx)("span", { className: `text-sm ${themeClasses.textPrimary}`, children: email }), (0, jsx_runtime_1.jsx)("button", { onClick: () => removeRecipient(email), className: `p-0.5 rounded ${isDark ? 'hover:bg-slate-600' : 'hover:bg-gray-300'} transition-colors`, children: (0, jsx_runtime_1.jsx)(lucide_react_1.X, { size: 14, className: themeClasses.textMuted }) })] }, email))), editedRecipients.length === 0 && ((0, jsx_runtime_1.jsx)("span", { className: `text-sm ${themeClasses.textMuted}`, children: "No recipients configured" }))] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex-1", children: [(0, jsx_runtime_1.jsx)("input", { type: "email", value: newRecipient, onChange: (e) => {
273
- setNewRecipient(e.target.value);
274
- setRecipientError(null);
275
- }, onKeyDown: (e) => {
276
- if (e.key === 'Enter') {
277
- e.preventDefault();
278
- addRecipient();
279
- }
280
- }, placeholder: "Enter email address", className: `
281
- w-full px-3 py-2 rounded-lg text-sm
282
- ${themeClasses.inputBg} ${themeClasses.textPrimary} border
283
- focus:outline-none focus:ring-2 focus:ring-indigo-500
284
- ${recipientError ? (isDark ? 'border-red-500' : 'border-red-400') : ''}
285
- ` }), recipientError && ((0, jsx_runtime_1.jsx)("p", { className: `text-xs mt-1 ${isDark ? 'text-red-400' : 'text-red-500'}`, children: recipientError }))] }), (0, jsx_runtime_1.jsxs)("button", { onClick: addRecipient, className: `
286
- px-4 py-2 rounded-lg font-medium text-sm transition-colors
287
- ${isDark ? 'bg-indigo-600 hover:bg-indigo-700' : 'bg-indigo-500 hover:bg-indigo-600'}
288
- text-white flex items-center gap-2
289
- `, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Plus, { size: 16 }), "Add"] })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-xl overflow-hidden`, children: [(0, jsx_runtime_1.jsxs)("div", { className: `px-5 py-4 border-b ${isDark ? 'border-slate-700' : 'border-gray-200'}`, children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Clock, { className: isDark ? 'text-cyan-400' : 'text-cyan-500', size: 20 }), (0, jsx_runtime_1.jsx)("h3", { className: `font-semibold ${themeClasses.textPrimary}`, children: "Delivery Mode" })] }), (0, jsx_runtime_1.jsx)("p", { className: `text-sm ${themeClasses.textMuted} mt-1`, children: "How alerts are delivered to recipients" })] }), (0, jsx_runtime_1.jsx)("div", { className: "p-5", children: (0, jsx_runtime_1.jsx)("div", { className: "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-3", children: DELIVERY_MODES.map((mode) => {
290
- const isSelected = editedMode === mode.value;
291
- return ((0, jsx_runtime_1.jsxs)("button", { onClick: () => setEditedMode(mode.value), className: `
292
- p-4 rounded-lg border-2 text-left transition-all
293
- ${isSelected
294
- ? 'border-indigo-500 ' + (isDark ? 'bg-indigo-500/10' : 'bg-indigo-50')
295
- : (isDark ? 'border-slate-700 hover:border-slate-600' : 'border-gray-200 hover:border-gray-300')}
296
- `, children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 mb-1", children: [(0, jsx_runtime_1.jsx)("div", { className: `w-3 h-3 rounded-full border-2 flex items-center justify-center ${isSelected ? 'border-indigo-500' : (isDark ? 'border-slate-500' : 'border-gray-400')}`, children: isSelected && (0, jsx_runtime_1.jsx)("div", { className: "w-1.5 h-1.5 rounded-full bg-indigo-500" }) }), (0, jsx_runtime_1.jsx)("span", { className: `font-medium ${themeClasses.textPrimary}`, children: mode.label })] }), (0, jsx_runtime_1.jsx)("p", { className: `text-xs ${themeClasses.textMuted} ml-5`, children: mode.description })] }, mode.value));
297
- }) }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-xl overflow-hidden`, children: [(0, jsx_runtime_1.jsxs)("div", { className: `px-5 py-4 border-b ${isDark ? 'border-slate-700' : 'border-gray-200'}`, children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Bell, { className: isDark ? 'text-amber-400' : 'text-amber-500', size: 20 }), (0, jsx_runtime_1.jsx)("h3", { className: `font-semibold ${themeClasses.textPrimary}`, children: "Alert Types" })] }), (0, jsx_runtime_1.jsx)("p", { className: `text-sm ${themeClasses.textMuted} mt-1`, children: "Configure which alerts to receive and their thresholds" })] }), (0, jsx_runtime_1.jsx)("div", { className: "divide-y divide-slate-700/50", children: ALERT_TYPES.map((alertType) => {
298
- const config = editedAlerts[alertType.id];
299
- const Icon = alertType.icon;
300
- return ((0, jsx_runtime_1.jsx)("div", { className: "p-5", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-start justify-between gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-start gap-3", children: [(0, jsx_runtime_1.jsx)("div", { className: `p-2 rounded-lg ${isDark ? 'bg-slate-700' : 'bg-gray-100'}`, children: (0, jsx_runtime_1.jsx)(Icon, { size: 18, className: themeClasses.textSecondary }) }), (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: `font-medium ${themeClasses.textPrimary}`, children: alertType.label }), alertType.alwaysSent && ((0, jsx_runtime_1.jsx)("span", { className: `px-2 py-0.5 text-xs rounded ${isDark ? 'bg-red-500/20 text-red-400' : 'bg-red-100 text-red-600'}`, children: "Always sent" }))] }), (0, jsx_runtime_1.jsx)("p", { className: `text-sm ${themeClasses.textMuted}`, children: alertType.description })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-4", children: [alertType.hasThreshold && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("input", { type: "number", min: "1", max: "100", value: config.threshold ?? config.threshold_pct ?? 10, onChange: (e) => {
301
- const val = parseInt(e.target.value) || 10;
302
- if (alertType.thresholdUnit?.includes('%')) {
303
- updateAlertConfig(alertType.id, { threshold_pct: val });
304
- }
305
- else {
306
- updateAlertConfig(alertType.id, { threshold: val });
307
- }
308
- }, disabled: !config.enabled && !alertType.alwaysSent, className: `
309
- w-16 px-2 py-1.5 rounded text-sm text-center
310
- ${themeClasses.inputBg} ${themeClasses.textPrimary} border
311
- focus:outline-none focus:ring-2 focus:ring-indigo-500
312
- disabled:opacity-50
313
- ` }), (0, jsx_runtime_1.jsx)("span", { className: `text-xs ${themeClasses.textMuted} whitespace-nowrap`, children: alertType.thresholdUnit })] })), !alertType.alwaysSent && ((0, jsx_runtime_1.jsx)("button", { onClick: () => updateAlertConfig(alertType.id, { enabled: !config.enabled }), className: `
314
- relative w-11 h-6 rounded-full transition-colors
315
- ${config.enabled
316
- ? (isDark ? 'bg-indigo-600' : 'bg-indigo-500')
317
- : (isDark ? 'bg-slate-600' : 'bg-gray-300')}
318
- `, children: (0, jsx_runtime_1.jsx)("span", { className: `
319
- absolute top-1 left-1 w-4 h-4 rounded-full bg-white transition-transform
320
- ${config.enabled ? 'translate-x-5' : ''}
321
- ` }) }))] })] }) }, alertType.id));
322
- }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-xl overflow-hidden`, children: [(0, jsx_runtime_1.jsx)("div", { className: `px-5 py-4 border-b ${isDark ? 'border-slate-700' : 'border-gray-200'}`, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Zap, { className: isDark ? 'text-emerald-400' : 'text-emerald-500', size: 20 }), (0, jsx_runtime_1.jsx)("h3", { className: `font-semibold ${themeClasses.textPrimary}`, children: "Rate Limiting" })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "p-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-4", children: [(0, jsx_runtime_1.jsx)("label", { className: `text-sm ${themeClasses.textSecondary}`, children: "Maximum alerts:" }), (0, jsx_runtime_1.jsx)("input", { type: "number", min: "1", max: "100", value: editedRateLimit, onChange: (e) => setEditedRateLimit(parseInt(e.target.value) || 10), className: `
323
- w-20 px-3 py-2 rounded-lg text-sm
324
- ${themeClasses.inputBg} ${themeClasses.textPrimary} border
325
- focus:outline-none focus:ring-2 focus:ring-indigo-500
326
- ` }), (0, jsx_runtime_1.jsx)("span", { className: `text-sm ${themeClasses.textMuted}`, children: "per hour" })] }), (0, jsx_runtime_1.jsxs)("div", { className: `flex items-start gap-2 mt-3 text-xs ${themeClasses.textMuted}`, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Info, { size: 14, className: "flex-shrink-0 mt-0.5" }), (0, jsx_runtime_1.jsx)("span", { children: "Critical alerts (Storage Critical, Agent Expired) are always sent regardless of this limit." })] })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-xl overflow-hidden`, children: [(0, jsx_runtime_1.jsx)("div", { className: `px-5 py-4 border-b ${isDark ? 'border-slate-700' : 'border-gray-200'}`, children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Send, { className: isDark ? 'text-blue-400' : 'text-blue-500', size: 20 }), (0, jsx_runtime_1.jsx)("h3", { className: `font-semibold ${themeClasses.textPrimary}`, children: "Test & History" })] }) }), (0, jsx_runtime_1.jsxs)("div", { className: "p-5", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex flex-wrap gap-3", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsxs)("select", { disabled: sendingTest || editedRecipients.length === 0, onChange: (e) => {
327
- if (e.target.value) {
328
- sendTestAlert(e.target.value);
329
- e.target.value = '';
330
- }
331
- }, className: `
332
- px-4 py-2.5 pr-10 rounded-lg text-sm font-medium cursor-pointer appearance-none
333
- ${isDark ? 'bg-blue-900/30 text-blue-300 border-blue-700 hover:bg-blue-900/50' : 'bg-blue-50 text-blue-700 border-blue-300 hover:bg-blue-100'}
334
- border focus:outline-none focus:ring-2 focus:ring-blue-500
335
- disabled:opacity-50 disabled:cursor-not-allowed
336
- `, children: [(0, jsx_runtime_1.jsx)("option", { value: "", children: "Send Test Alert..." }), TEST_ALERT_OPTIONS.map((opt) => ((0, jsx_runtime_1.jsx)("option", { value: opt.value, children: opt.label }, opt.value)))] }), (0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { className: `absolute right-3 top-1/2 -translate-y-1/2 w-4 h-4 pointer-events-none ${isDark ? 'text-blue-400' : 'text-blue-500'}` })] }), (0, jsx_runtime_1.jsxs)("button", { onClick: () => {
337
- // TODO: Open history modal or navigate to history page
338
- window.open(`${apiBasePath}/history`, '_blank');
339
- }, className: `
340
- px-4 py-2.5 rounded-lg text-sm font-medium flex items-center gap-2
341
- ${isDark ? 'bg-slate-700 text-white hover:bg-slate-600' : 'bg-gray-100 text-gray-700 hover:bg-gray-200'}
342
- border ${isDark ? 'border-slate-600' : 'border-gray-300'}
343
- `, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.History, { size: 16 }), "View Alert History"] })] }), editedRecipients.length === 0 && ((0, jsx_runtime_1.jsx)("p", { className: `text-xs mt-3 ${themeClasses.textMuted}`, children: "Add at least one recipient to send test alerts." }))] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-end gap-4", children: [hasChanges && ((0, jsx_runtime_1.jsx)("span", { className: `text-sm ${themeClasses.textMuted}`, children: "You have unsaved changes" })), (0, jsx_runtime_1.jsx)("button", { onClick: saveSettings, disabled: !hasChanges || saving, className: `
344
- px-6 py-2.5 rounded-lg font-medium text-sm transition-all
345
- ${hasChanges
346
- ? 'bg-indigo-600 text-white hover:bg-indigo-700'
347
- : (isDark ? 'bg-slate-700 text-slate-400' : 'bg-gray-200 text-gray-400')}
348
- disabled:cursor-not-allowed
349
- `, children: saving ? ((0, jsx_runtime_1.jsxs)("span", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCw, { className: "w-4 h-4 animate-spin" }), "Saving..."] })) : ('Save Settings') })] })] }));
350
- }
351
- exports.default = AlertSettingsTab;