@payez/next-mvp 3.9.1 → 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 (526) hide show
  1. package/package.json +6 -18
  2. package/src/api/auth-handler.ts +550 -549
  3. package/src/api-handlers/account/change-password.ts +5 -8
  4. package/src/api-handlers/admin/analytics.ts +4 -6
  5. package/src/api-handlers/admin/audit.ts +5 -7
  6. package/src/api-handlers/admin/index.ts +1 -2
  7. package/src/api-handlers/admin/redis-sessions.ts +6 -8
  8. package/src/api-handlers/admin/sessions.ts +5 -7
  9. package/src/api-handlers/admin/site-logs.ts +8 -10
  10. package/src/api-handlers/admin/stats.ts +4 -6
  11. package/src/api-handlers/admin/users.ts +5 -7
  12. package/src/api-handlers/admin/vibe-data.ts +10 -12
  13. package/src/api-handlers/auth/refresh.ts +5 -7
  14. package/src/api-handlers/auth/signout.ts +5 -6
  15. package/src/api-handlers/auth/status.ts +4 -7
  16. package/src/api-handlers/auth/update-session.ts +123 -125
  17. package/src/api-handlers/auth/verify-code.ts +9 -13
  18. package/src/api-handlers/session/viability.ts +10 -47
  19. package/src/api-handlers/test/force-expire.ts +4 -11
  20. package/src/auth/auth-decision.ts +1 -1
  21. package/src/auth/better-auth.ts +138 -141
  22. package/src/auth/route-config.ts +219 -219
  23. package/src/auth/utils/token-utils.ts +0 -1
  24. package/src/client/AuthContext.tsx +6 -2
  25. package/src/client/fetch-with-auth.ts +47 -47
  26. package/src/components/SessionSync.tsx +6 -5
  27. package/src/components/account/MobileNavDrawer.tsx +3 -3
  28. package/src/components/account/UserAvatarMenu.tsx +6 -3
  29. package/src/components/admin/VibeAdminLayout.tsx +4 -2
  30. package/src/config/logger.ts +1 -1
  31. package/src/hooks/useAuth.ts +117 -115
  32. package/src/hooks/useAuthSettings.ts +2 -2
  33. package/src/hooks/useAvailableProviders.ts +9 -5
  34. package/src/hooks/useSessionExpiration.ts +101 -102
  35. package/src/hooks/useViabilitySession.ts +336 -335
  36. package/src/index.ts +60 -63
  37. package/src/lib/api-handler.ts +0 -1
  38. package/src/lib/app-slug.ts +6 -6
  39. package/src/lib/standardized-client-api.ts +901 -895
  40. package/src/lib/startup-init.ts +243 -247
  41. package/src/lib/test-aware-get-token.ts +22 -12
  42. package/src/lib/token-lifecycle.ts +12 -53
  43. package/src/pages/admin-login/page.tsx +9 -17
  44. package/src/pages/client-admin/ClientSiteAdminPage.tsx +4 -2
  45. package/src/pages/login/page.tsx +21 -28
  46. package/src/pages/showcase/ShowcasePage.tsx +4 -2
  47. package/src/pages/test-env/EmergencyLogoutPage.tsx +7 -6
  48. package/src/pages/test-env/JwtInspectPage.tsx +5 -3
  49. package/src/pages/test-env/RefreshTokenPage.tsx +157 -155
  50. package/src/pages/test-env/TestEnvPage.tsx +4 -2
  51. package/src/pages/verify-code/page.tsx +10 -6
  52. package/src/routes/auth/logout.ts +7 -25
  53. package/src/routes/auth/nextauth.ts +45 -71
  54. package/src/routes/auth/session.ts +25 -50
  55. package/src/routes/auth/viability.ts +7 -19
  56. package/src/server/auth.ts +60 -0
  57. package/src/stores/authStore.ts +1899 -1904
  58. package/src/utils/logout.ts +30 -30
  59. package/dist/api/auth-handler.d.ts +0 -67
  60. package/dist/api/auth-handler.js +0 -397
  61. package/dist/api/index.d.ts +0 -10
  62. package/dist/api/index.js +0 -19
  63. package/dist/api-handlers/account/change-password.d.ts +0 -9
  64. package/dist/api-handlers/account/change-password.js +0 -112
  65. package/dist/api-handlers/account/masked-info.d.ts +0 -2
  66. package/dist/api-handlers/account/masked-info.js +0 -41
  67. package/dist/api-handlers/account/profile.d.ts +0 -3
  68. package/dist/api-handlers/account/profile.js +0 -63
  69. package/dist/api-handlers/account/recovery/initiate.d.ts +0 -2
  70. package/dist/api-handlers/account/recovery/initiate.js +0 -26
  71. package/dist/api-handlers/account/recovery/send-code.d.ts +0 -2
  72. package/dist/api-handlers/account/recovery/send-code.js +0 -28
  73. package/dist/api-handlers/account/recovery/verify-code.d.ts +0 -2
  74. package/dist/api-handlers/account/recovery/verify-code.js +0 -28
  75. package/dist/api-handlers/account/reset-password.d.ts +0 -2
  76. package/dist/api-handlers/account/reset-password.js +0 -26
  77. package/dist/api-handlers/account/send-code.d.ts +0 -24
  78. package/dist/api-handlers/account/send-code.js +0 -60
  79. package/dist/api-handlers/account/update-phone.d.ts +0 -27
  80. package/dist/api-handlers/account/update-phone.js +0 -64
  81. package/dist/api-handlers/account/validate-password.d.ts +0 -17
  82. package/dist/api-handlers/account/validate-password.js +0 -81
  83. package/dist/api-handlers/account/verify-email.d.ts +0 -26
  84. package/dist/api-handlers/account/verify-email.js +0 -106
  85. package/dist/api-handlers/account/verify-sms.d.ts +0 -26
  86. package/dist/api-handlers/account/verify-sms.js +0 -106
  87. package/dist/api-handlers/admin/analytics.d.ts +0 -20
  88. package/dist/api-handlers/admin/analytics.js +0 -379
  89. package/dist/api-handlers/admin/audit.d.ts +0 -20
  90. package/dist/api-handlers/admin/audit.js +0 -214
  91. package/dist/api-handlers/admin/index.d.ts +0 -22
  92. package/dist/api-handlers/admin/index.js +0 -43
  93. package/dist/api-handlers/admin/redis-sessions.d.ts +0 -36
  94. package/dist/api-handlers/admin/redis-sessions.js +0 -204
  95. package/dist/api-handlers/admin/sessions.d.ts +0 -21
  96. package/dist/api-handlers/admin/sessions.js +0 -284
  97. package/dist/api-handlers/admin/site-logs.d.ts +0 -46
  98. package/dist/api-handlers/admin/site-logs.js +0 -318
  99. package/dist/api-handlers/admin/stats.d.ts +0 -21
  100. package/dist/api-handlers/admin/stats.js +0 -240
  101. package/dist/api-handlers/admin/users.d.ts +0 -20
  102. package/dist/api-handlers/admin/users.js +0 -222
  103. package/dist/api-handlers/admin/vibe-data.d.ts +0 -80
  104. package/dist/api-handlers/admin/vibe-data.js +0 -268
  105. package/dist/api-handlers/anon/preferences.d.ts +0 -37
  106. package/dist/api-handlers/anon/preferences.js +0 -96
  107. package/dist/api-handlers/auth/jwks.d.ts +0 -2
  108. package/dist/api-handlers/auth/jwks.js +0 -24
  109. package/dist/api-handlers/auth/login.d.ts +0 -42
  110. package/dist/api-handlers/auth/login.js +0 -178
  111. package/dist/api-handlers/auth/refresh.d.ts +0 -74
  112. package/dist/api-handlers/auth/refresh.js +0 -635
  113. package/dist/api-handlers/auth/signout.d.ts +0 -37
  114. package/dist/api-handlers/auth/signout.js +0 -187
  115. package/dist/api-handlers/auth/status.d.ts +0 -8
  116. package/dist/api-handlers/auth/status.js +0 -26
  117. package/dist/api-handlers/auth/update-session.d.ts +0 -37
  118. package/dist/api-handlers/auth/update-session.js +0 -95
  119. package/dist/api-handlers/auth/validate.d.ts +0 -6
  120. package/dist/api-handlers/auth/validate.js +0 -43
  121. package/dist/api-handlers/auth/verify-code.d.ts +0 -43
  122. package/dist/api-handlers/auth/verify-code.js +0 -94
  123. package/dist/api-handlers/session/refresh-viability.d.ts +0 -14
  124. package/dist/api-handlers/session/refresh-viability.js +0 -39
  125. package/dist/api-handlers/session/viability.d.ts +0 -13
  126. package/dist/api-handlers/session/viability.js +0 -146
  127. package/dist/api-handlers/test/force-expire.d.ts +0 -23
  128. package/dist/api-handlers/test/force-expire.js +0 -65
  129. package/dist/auth/auth-decision.d.ts +0 -39
  130. package/dist/auth/auth-decision.js +0 -182
  131. package/dist/auth/auth-options.d.ts +0 -57
  132. package/dist/auth/auth-options.js +0 -213
  133. package/dist/auth/better-auth.d.ts +0 -82
  134. package/dist/auth/better-auth.js +0 -122
  135. package/dist/auth/callbacks/index.d.ts +0 -6
  136. package/dist/auth/callbacks/index.js +0 -12
  137. package/dist/auth/callbacks/jwt.d.ts +0 -45
  138. package/dist/auth/callbacks/jwt.js +0 -305
  139. package/dist/auth/callbacks/session.d.ts +0 -60
  140. package/dist/auth/callbacks/session.js +0 -170
  141. package/dist/auth/callbacks/signin.d.ts +0 -23
  142. package/dist/auth/callbacks/signin.js +0 -44
  143. package/dist/auth/events/index.d.ts +0 -4
  144. package/dist/auth/events/index.js +0 -8
  145. package/dist/auth/events/signout.d.ts +0 -17
  146. package/dist/auth/events/signout.js +0 -32
  147. package/dist/auth/providers/credentials.d.ts +0 -32
  148. package/dist/auth/providers/credentials.js +0 -223
  149. package/dist/auth/providers/index.d.ts +0 -5
  150. package/dist/auth/providers/index.js +0 -21
  151. package/dist/auth/providers/oauth.d.ts +0 -26
  152. package/dist/auth/providers/oauth.js +0 -105
  153. package/dist/auth/route-config.d.ts +0 -66
  154. package/dist/auth/route-config.js +0 -190
  155. package/dist/auth/types/auth-types.d.ts +0 -417
  156. package/dist/auth/types/auth-types.js +0 -53
  157. package/dist/auth/types/index.d.ts +0 -6
  158. package/dist/auth/types/index.js +0 -22
  159. package/dist/auth/unauthenticated-routes.d.ts +0 -1
  160. package/dist/auth/unauthenticated-routes.js +0 -19
  161. package/dist/auth/utils/idp-client.d.ts +0 -94
  162. package/dist/auth/utils/idp-client.js +0 -384
  163. package/dist/auth/utils/index.d.ts +0 -5
  164. package/dist/auth/utils/index.js +0 -21
  165. package/dist/auth/utils/token-utils.d.ts +0 -84
  166. package/dist/auth/utils/token-utils.js +0 -219
  167. package/dist/client/AuthContext.d.ts +0 -19
  168. package/dist/client/AuthContext.js +0 -112
  169. package/dist/client/better-auth-client.d.ts +0 -1020
  170. package/dist/client/better-auth-client.js +0 -68
  171. package/dist/client/fetch-with-auth.d.ts +0 -11
  172. package/dist/client/fetch-with-auth.js +0 -44
  173. package/dist/client/fetchWithSession.d.ts +0 -3
  174. package/dist/client/fetchWithSession.js +0 -24
  175. package/dist/client/index.d.ts +0 -9
  176. package/dist/client/index.js +0 -20
  177. package/dist/client/useAnonSession.d.ts +0 -36
  178. package/dist/client/useAnonSession.js +0 -99
  179. package/dist/components/SessionSync.d.ts +0 -13
  180. package/dist/components/SessionSync.js +0 -119
  181. package/dist/components/SignalRHealthCheck.d.ts +0 -10
  182. package/dist/components/SignalRHealthCheck.js +0 -97
  183. package/dist/components/account/MobileNavDrawer.d.ts +0 -32
  184. package/dist/components/account/MobileNavDrawer.js +0 -81
  185. package/dist/components/account/UserAvatarMenu.d.ts +0 -20
  186. package/dist/components/account/UserAvatarMenu.js +0 -88
  187. package/dist/components/account/index.d.ts +0 -9
  188. package/dist/components/account/index.js +0 -13
  189. package/dist/components/admin/AlertSettingsTab.d.ts +0 -48
  190. package/dist/components/admin/AlertSettingsTab.js +0 -351
  191. package/dist/components/admin/AnalyticsTab.d.ts +0 -22
  192. package/dist/components/admin/AnalyticsTab.js +0 -167
  193. package/dist/components/admin/DataBrowserTab.d.ts +0 -19
  194. package/dist/components/admin/DataBrowserTab.js +0 -252
  195. package/dist/components/admin/LoggingSettingsTab.d.ts +0 -73
  196. package/dist/components/admin/LoggingSettingsTab.js +0 -339
  197. package/dist/components/admin/SessionsTab.d.ts +0 -37
  198. package/dist/components/admin/SessionsTab.js +0 -165
  199. package/dist/components/admin/StatsTab.d.ts +0 -53
  200. package/dist/components/admin/StatsTab.js +0 -161
  201. package/dist/components/admin/VibeAdminContext.d.ts +0 -32
  202. package/dist/components/admin/VibeAdminContext.js +0 -38
  203. package/dist/components/admin/VibeAdminLayout.d.ts +0 -11
  204. package/dist/components/admin/VibeAdminLayout.js +0 -69
  205. package/dist/components/admin/index.d.ts +0 -29
  206. package/dist/components/admin/index.js +0 -44
  207. package/dist/components/auth/FederatedAuthSection.d.ts +0 -8
  208. package/dist/components/auth/FederatedAuthSection.js +0 -45
  209. package/dist/components/auth/ModeAwareLoginPage.d.ts +0 -10
  210. package/dist/components/auth/ModeAwareLoginPage.js +0 -42
  211. package/dist/components/auth/ModeAwareSignupPage.d.ts +0 -9
  212. package/dist/components/auth/ModeAwareSignupPage.js +0 -78
  213. package/dist/components/auth/TraditionalAuthSection.d.ts +0 -14
  214. package/dist/components/auth/TraditionalAuthSection.js +0 -20
  215. package/dist/components/recovery/CompleteStep.d.ts +0 -5
  216. package/dist/components/recovery/CompleteStep.js +0 -8
  217. package/dist/components/recovery/InitiateRecoveryStep.d.ts +0 -8
  218. package/dist/components/recovery/InitiateRecoveryStep.js +0 -20
  219. package/dist/components/recovery/SelectMethodStep.d.ts +0 -8
  220. package/dist/components/recovery/SelectMethodStep.js +0 -8
  221. package/dist/components/recovery/SetPasswordStep.d.ts +0 -6
  222. package/dist/components/recovery/SetPasswordStep.js +0 -20
  223. package/dist/components/recovery/VerifyCodeStep.d.ts +0 -10
  224. package/dist/components/recovery/VerifyCodeStep.js +0 -24
  225. package/dist/components/reserved/ReservedRecoveryWarning.d.ts +0 -38
  226. package/dist/components/reserved/ReservedRecoveryWarning.js +0 -92
  227. package/dist/components/reserved/ReservedStatusBox.d.ts +0 -30
  228. package/dist/components/reserved/ReservedStatusBox.js +0 -71
  229. package/dist/components/ui/BetaBadge.d.ts +0 -29
  230. package/dist/components/ui/BetaBadge.js +0 -38
  231. package/dist/components/ui/Footer.d.ts +0 -37
  232. package/dist/components/ui/Footer.js +0 -41
  233. package/dist/config/env.d.ts +0 -66
  234. package/dist/config/env.js +0 -57
  235. package/dist/config/logger.d.ts +0 -57
  236. package/dist/config/logger.js +0 -73
  237. package/dist/config/logging-config.d.ts +0 -30
  238. package/dist/config/logging-config.js +0 -122
  239. package/dist/config/unauthenticated-routes.d.ts +0 -17
  240. package/dist/config/unauthenticated-routes.js +0 -24
  241. package/dist/config/vibe-log-transport.d.ts +0 -81
  242. package/dist/config/vibe-log-transport.js +0 -212
  243. package/dist/edge/internal-api-url.d.ts +0 -53
  244. package/dist/edge/internal-api-url.js +0 -63
  245. package/dist/edge/middleware.d.ts +0 -14
  246. package/dist/edge/middleware.js +0 -32
  247. package/dist/hooks/useAuth.d.ts +0 -23
  248. package/dist/hooks/useAuth.js +0 -81
  249. package/dist/hooks/useAuthSettings.d.ts +0 -59
  250. package/dist/hooks/useAuthSettings.js +0 -93
  251. package/dist/hooks/useAvailableProviders.d.ts +0 -45
  252. package/dist/hooks/useAvailableProviders.js +0 -108
  253. package/dist/hooks/usePasswordValidation.d.ts +0 -27
  254. package/dist/hooks/usePasswordValidation.js +0 -102
  255. package/dist/hooks/useProfile.d.ts +0 -15
  256. package/dist/hooks/useProfile.js +0 -59
  257. package/dist/hooks/usePublicAuthSettings.d.ts +0 -56
  258. package/dist/hooks/usePublicAuthSettings.js +0 -131
  259. package/dist/hooks/useSessionExpiration.d.ts +0 -57
  260. package/dist/hooks/useSessionExpiration.js +0 -72
  261. package/dist/hooks/useViabilitySession.d.ts +0 -75
  262. package/dist/hooks/useViabilitySession.js +0 -268
  263. package/dist/index.d.ts +0 -12
  264. package/dist/index.js +0 -55
  265. package/dist/lib/anon-session.d.ts +0 -74
  266. package/dist/lib/anon-session.js +0 -169
  267. package/dist/lib/api-handler.d.ts +0 -123
  268. package/dist/lib/api-handler.js +0 -478
  269. package/dist/lib/app-slug.d.ts +0 -95
  270. package/dist/lib/app-slug.js +0 -172
  271. package/dist/lib/demo-mode.d.ts +0 -6
  272. package/dist/lib/demo-mode.js +0 -16
  273. package/dist/lib/geolocation.d.ts +0 -64
  274. package/dist/lib/geolocation.js +0 -235
  275. package/dist/lib/idp-client-config.d.ts +0 -75
  276. package/dist/lib/idp-client-config.js +0 -425
  277. package/dist/lib/idp-fetch.d.ts +0 -14
  278. package/dist/lib/idp-fetch.js +0 -91
  279. package/dist/lib/internal-api.d.ts +0 -87
  280. package/dist/lib/internal-api.js +0 -122
  281. package/dist/lib/jwt-decode-client.d.ts +0 -10
  282. package/dist/lib/jwt-decode-client.js +0 -46
  283. package/dist/lib/jwt-decode.d.ts +0 -48
  284. package/dist/lib/jwt-decode.js +0 -57
  285. package/dist/lib/nextauth-secret.d.ts +0 -10
  286. package/dist/lib/nextauth-secret.js +0 -100
  287. package/dist/lib/rate-limit-service.d.ts +0 -23
  288. package/dist/lib/rate-limit-service.js +0 -6
  289. package/dist/lib/redis.d.ts +0 -5
  290. package/dist/lib/redis.js +0 -28
  291. package/dist/lib/refresh-token-validator.d.ts +0 -13
  292. package/dist/lib/refresh-token-validator.js +0 -117
  293. package/dist/lib/roles.d.ts +0 -145
  294. package/dist/lib/roles.js +0 -168
  295. package/dist/lib/secret-validation.d.ts +0 -4
  296. package/dist/lib/secret-validation.js +0 -14
  297. package/dist/lib/session-store.d.ts +0 -170
  298. package/dist/lib/session-store.js +0 -545
  299. package/dist/lib/session.d.ts +0 -21
  300. package/dist/lib/session.js +0 -26
  301. package/dist/lib/site-logger.d.ts +0 -214
  302. package/dist/lib/site-logger.js +0 -210
  303. package/dist/lib/standardized-client-api.d.ts +0 -161
  304. package/dist/lib/standardized-client-api.js +0 -786
  305. package/dist/lib/startup-init.d.ts +0 -40
  306. package/dist/lib/startup-init.js +0 -261
  307. package/dist/lib/test-aware-get-token.d.ts +0 -2
  308. package/dist/lib/test-aware-get-token.js +0 -81
  309. package/dist/lib/token-expiry.d.ts +0 -14
  310. package/dist/lib/token-expiry.js +0 -39
  311. package/dist/lib/token-lifecycle.d.ts +0 -52
  312. package/dist/lib/token-lifecycle.js +0 -398
  313. package/dist/lib/types/api-responses.d.ts +0 -128
  314. package/dist/lib/types/api-responses.js +0 -171
  315. package/dist/lib/user-agent-parser.d.ts +0 -50
  316. package/dist/lib/user-agent-parser.js +0 -220
  317. package/dist/logging/api/admin-analytics.d.ts +0 -3
  318. package/dist/logging/api/admin-analytics.js +0 -45
  319. package/dist/logging/api/audit-log.d.ts +0 -3
  320. package/dist/logging/api/audit-log.js +0 -52
  321. package/dist/logging/components/AdminAnalyticsLayout.d.ts +0 -10
  322. package/dist/logging/components/AdminAnalyticsLayout.js +0 -11
  323. package/dist/logging/components/AuditLogViewer.d.ts +0 -7
  324. package/dist/logging/components/AuditLogViewer.js +0 -51
  325. package/dist/logging/components/ErrorMetricsCard.d.ts +0 -7
  326. package/dist/logging/components/ErrorMetricsCard.js +0 -16
  327. package/dist/logging/components/HealthMetricsCard.d.ts +0 -7
  328. package/dist/logging/components/HealthMetricsCard.js +0 -19
  329. package/dist/logging/hooks/useAdminAnalytics.d.ts +0 -24
  330. package/dist/logging/hooks/useAdminAnalytics.js +0 -22
  331. package/dist/logging/hooks/useAuditLog.d.ts +0 -6
  332. package/dist/logging/hooks/useAuditLog.js +0 -25
  333. package/dist/logging/hooks/useErrorMetrics.d.ts +0 -6
  334. package/dist/logging/hooks/useErrorMetrics.js +0 -38
  335. package/dist/logging/hooks/useHealthMetrics.d.ts +0 -6
  336. package/dist/logging/hooks/useHealthMetrics.js +0 -41
  337. package/dist/logging/index.d.ts +0 -11
  338. package/dist/logging/index.js +0 -40
  339. package/dist/logging/types/analytics.d.ts +0 -68
  340. package/dist/logging/types/analytics.js +0 -3
  341. package/dist/logging/types/audit.d.ts +0 -29
  342. package/dist/logging/types/audit.js +0 -2
  343. package/dist/logging/types/index.d.ts +0 -2
  344. package/dist/logging/types/index.js +0 -19
  345. package/dist/middleware/auth-decision.d.ts +0 -33
  346. package/dist/middleware/auth-decision.js +0 -65
  347. package/dist/middleware/create-middleware.d.ts +0 -102
  348. package/dist/middleware/create-middleware.js +0 -469
  349. package/dist/middleware/rbac-check.d.ts +0 -51
  350. package/dist/middleware/rbac-check.js +0 -219
  351. package/dist/middleware/twofa-presets.d.ts +0 -134
  352. package/dist/middleware/twofa-presets.js +0 -175
  353. package/dist/models/DecodedAccessToken.d.ts +0 -17
  354. package/dist/models/DecodedAccessToken.js +0 -2
  355. package/dist/models/SessionModel.d.ts +0 -122
  356. package/dist/models/SessionModel.js +0 -136
  357. package/dist/pages/admin-login/page.d.ts +0 -31
  358. package/dist/pages/admin-login/page.js +0 -83
  359. package/dist/pages/admin-page-permissions/PagePermissionsAdminPage.d.ts +0 -18
  360. package/dist/pages/admin-page-permissions/PagePermissionsAdminPage.js +0 -276
  361. package/dist/pages/admin-page-permissions/index.d.ts +0 -6
  362. package/dist/pages/admin-page-permissions/index.js +0 -13
  363. package/dist/pages/admin-roles/RolesAdminPage.d.ts +0 -16
  364. package/dist/pages/admin-roles/RolesAdminPage.js +0 -261
  365. package/dist/pages/admin-roles/index.d.ts +0 -8
  366. package/dist/pages/admin-roles/index.js +0 -15
  367. package/dist/pages/admin-roles/modals.d.ts +0 -72
  368. package/dist/pages/admin-roles/modals.js +0 -154
  369. package/dist/pages/client-admin/ClientSiteAdminPage.d.ts +0 -79
  370. package/dist/pages/client-admin/ClientSiteAdminPage.js +0 -177
  371. package/dist/pages/client-admin/index.d.ts +0 -32
  372. package/dist/pages/client-admin/index.js +0 -37
  373. package/dist/pages/coming-soon/page.d.ts +0 -8
  374. package/dist/pages/coming-soon/page.js +0 -28
  375. package/dist/pages/login/page.d.ts +0 -22
  376. package/dist/pages/login/page.js +0 -239
  377. package/dist/pages/profile/EnhancedProfilePage.d.ts +0 -13
  378. package/dist/pages/profile/EnhancedProfilePage.js +0 -150
  379. package/dist/pages/profile/index.d.ts +0 -8
  380. package/dist/pages/profile/index.js +0 -16
  381. package/dist/pages/profile/page.d.ts +0 -19
  382. package/dist/pages/profile/page.js +0 -47
  383. package/dist/pages/profile/profile-patch.d.ts +0 -1
  384. package/dist/pages/profile/profile-patch.js +0 -281
  385. package/dist/pages/recovery/page.d.ts +0 -1
  386. package/dist/pages/recovery/page.js +0 -142
  387. package/dist/pages/roles/MyRolesPage.d.ts +0 -24
  388. package/dist/pages/roles/MyRolesPage.js +0 -71
  389. package/dist/pages/roles/components.d.ts +0 -63
  390. package/dist/pages/roles/components.js +0 -108
  391. package/dist/pages/roles/index.d.ts +0 -8
  392. package/dist/pages/roles/index.js +0 -19
  393. package/dist/pages/security/EnhancedSecurityPage.d.ts +0 -14
  394. package/dist/pages/security/EnhancedSecurityPage.js +0 -248
  395. package/dist/pages/security/index.d.ts +0 -8
  396. package/dist/pages/security/index.js +0 -16
  397. package/dist/pages/security/page.d.ts +0 -21
  398. package/dist/pages/security/page.js +0 -212
  399. package/dist/pages/security/security-patch.d.ts +0 -1
  400. package/dist/pages/security/security-patch.js +0 -302
  401. package/dist/pages/settings/EnhancedSettingsPage.d.ts +0 -46
  402. package/dist/pages/settings/EnhancedSettingsPage.js +0 -231
  403. package/dist/pages/settings/index.d.ts +0 -8
  404. package/dist/pages/settings/index.js +0 -16
  405. package/dist/pages/settings/page.d.ts +0 -7
  406. package/dist/pages/settings/page.js +0 -26
  407. package/dist/pages/showcase/ShowcasePage.d.ts +0 -13
  408. package/dist/pages/showcase/ShowcasePage.js +0 -140
  409. package/dist/pages/showcase/index.d.ts +0 -12
  410. package/dist/pages/showcase/index.js +0 -17
  411. package/dist/pages/test-env/EmergencyLogoutPage.d.ts +0 -14
  412. package/dist/pages/test-env/EmergencyLogoutPage.js +0 -98
  413. package/dist/pages/test-env/JwtInspectPage.d.ts +0 -14
  414. package/dist/pages/test-env/JwtInspectPage.js +0 -114
  415. package/dist/pages/test-env/RefreshTokenPage.d.ts +0 -15
  416. package/dist/pages/test-env/RefreshTokenPage.js +0 -91
  417. package/dist/pages/test-env/TestEnvPage.d.ts +0 -13
  418. package/dist/pages/test-env/TestEnvPage.js +0 -49
  419. package/dist/pages/test-env/index.d.ts +0 -24
  420. package/dist/pages/test-env/index.js +0 -32
  421. package/dist/pages/verify-code/page.d.ts +0 -30
  422. package/dist/pages/verify-code/page.js +0 -408
  423. package/dist/routes/account/index.d.ts +0 -28
  424. package/dist/routes/account/index.js +0 -71
  425. package/dist/routes/account/masked-info.d.ts +0 -33
  426. package/dist/routes/account/masked-info.js +0 -39
  427. package/dist/routes/account/send-code.d.ts +0 -37
  428. package/dist/routes/account/send-code.js +0 -42
  429. package/dist/routes/account/update-phone.d.ts +0 -13
  430. package/dist/routes/account/update-phone.js +0 -17
  431. package/dist/routes/account/verify-email.d.ts +0 -38
  432. package/dist/routes/account/verify-email.js +0 -43
  433. package/dist/routes/account/verify-sms.d.ts +0 -38
  434. package/dist/routes/account/verify-sms.js +0 -43
  435. package/dist/routes/auth/index.d.ts +0 -19
  436. package/dist/routes/auth/index.js +0 -64
  437. package/dist/routes/auth/logout.d.ts +0 -31
  438. package/dist/routes/auth/logout.js +0 -113
  439. package/dist/routes/auth/nextauth.d.ts +0 -19
  440. package/dist/routes/auth/nextauth.js +0 -72
  441. package/dist/routes/auth/refresh.d.ts +0 -30
  442. package/dist/routes/auth/refresh.js +0 -51
  443. package/dist/routes/auth/session.d.ts +0 -43
  444. package/dist/routes/auth/session.js +0 -179
  445. package/dist/routes/auth/settings.d.ts +0 -25
  446. package/dist/routes/auth/settings.js +0 -55
  447. package/dist/routes/auth/viability.d.ts +0 -52
  448. package/dist/routes/auth/viability.js +0 -201
  449. package/dist/routes/index.d.ts +0 -12
  450. package/dist/routes/index.js +0 -54
  451. package/dist/routes/session/index.d.ts +0 -6
  452. package/dist/routes/session/index.js +0 -10
  453. package/dist/routes/session/refresh-viability.d.ts +0 -16
  454. package/dist/routes/session/refresh-viability.js +0 -20
  455. package/dist/server/auth-guard.d.ts +0 -46
  456. package/dist/server/auth-guard.js +0 -128
  457. package/dist/server/decode-session.d.ts +0 -30
  458. package/dist/server/decode-session.js +0 -78
  459. package/dist/server/slim-middleware.d.ts +0 -23
  460. package/dist/server/slim-middleware.js +0 -89
  461. package/dist/server/with-auth.d.ts +0 -33
  462. package/dist/server/with-auth.js +0 -59
  463. package/dist/services/signalrActivityService.d.ts +0 -44
  464. package/dist/services/signalrActivityService.js +0 -257
  465. package/dist/stores/authStore.d.ts +0 -154
  466. package/dist/stores/authStore.js +0 -1531
  467. package/dist/theme/ThemeProvider.d.ts +0 -14
  468. package/dist/theme/ThemeProvider.js +0 -28
  469. package/dist/theme/default.d.ts +0 -8
  470. package/dist/theme/default.js +0 -33
  471. package/dist/theme/index.d.ts +0 -15
  472. package/dist/theme/index.js +0 -25
  473. package/dist/theme/types.d.ts +0 -56
  474. package/dist/theme/types.js +0 -8
  475. package/dist/theme/useTheme.d.ts +0 -60
  476. package/dist/theme/useTheme.js +0 -63
  477. package/dist/theme/utils.d.ts +0 -13
  478. package/dist/theme/utils.js +0 -39
  479. package/dist/types/api.d.ts +0 -134
  480. package/dist/types/api.js +0 -44
  481. package/dist/types/auth.d.ts +0 -19
  482. package/dist/types/auth.js +0 -2
  483. package/dist/types/logging.d.ts +0 -42
  484. package/dist/types/logging.js +0 -2
  485. package/dist/types/recovery.d.ts +0 -48
  486. package/dist/types/recovery.js +0 -2
  487. package/dist/types/security.d.ts +0 -1
  488. package/dist/types/security.js +0 -2
  489. package/dist/utils/api.d.ts +0 -85
  490. package/dist/utils/api.js +0 -287
  491. package/dist/utils/circuitBreaker.d.ts +0 -43
  492. package/dist/utils/circuitBreaker.js +0 -91
  493. package/dist/utils/error-message.d.ts +0 -1
  494. package/dist/utils/error-message.js +0 -103
  495. package/dist/utils/layout/reservedSpace.d.ts +0 -59
  496. package/dist/utils/layout/reservedSpace.js +0 -102
  497. package/dist/utils/logout.d.ts +0 -14
  498. package/dist/utils/logout.js +0 -32
  499. package/dist/vibe/client.d.ts +0 -261
  500. package/dist/vibe/client.js +0 -445
  501. package/dist/vibe/enterprise-auth.d.ts +0 -106
  502. package/dist/vibe/enterprise-auth.js +0 -173
  503. package/dist/vibe/errors.d.ts +0 -83
  504. package/dist/vibe/errors.js +0 -146
  505. package/dist/vibe/generic.d.ts +0 -234
  506. package/dist/vibe/generic.js +0 -369
  507. package/dist/vibe/hooks/index.d.ts +0 -169
  508. package/dist/vibe/hooks/index.js +0 -252
  509. package/dist/vibe/index.d.ts +0 -25
  510. package/dist/vibe/index.js +0 -72
  511. package/dist/vibe/sessions.d.ts +0 -161
  512. package/dist/vibe/sessions.js +0 -391
  513. package/dist/vibe/types.d.ts +0 -353
  514. package/dist/vibe/types.js +0 -315
  515. package/src/auth/auth-options.ts +0 -237
  516. package/src/auth/callbacks/index.ts +0 -7
  517. package/src/auth/callbacks/jwt.ts +0 -382
  518. package/src/auth/callbacks/session.ts +0 -243
  519. package/src/auth/callbacks/signin.ts +0 -56
  520. package/src/auth/events/index.ts +0 -5
  521. package/src/auth/events/signout.ts +0 -33
  522. package/src/auth/providers/credentials.ts +0 -256
  523. package/src/auth/providers/index.ts +0 -6
  524. package/src/auth/providers/oauth.ts +0 -114
  525. package/src/lib/nextauth-secret.ts +0 -121
  526. package/src/types/next-auth.d.ts +0 -15
@@ -1,22 +0,0 @@
1
- /**
2
- * =============================================================================
3
- * VIBE ADMIN ANALYTICS TAB
4
- * =============================================================================
5
- *
6
- * Generic dashboard tab showing login statistics and analytics.
7
- * Can be extended by consumer apps with custom components.
8
- *
9
- * =============================================================================
10
- */
11
- import { ReactNode } from 'react';
12
- export interface AnalyticsTabProps {
13
- isDark?: boolean;
14
- /** Base API path for analytics (default: /api/admin/analytics) */
15
- apiBasePath?: string;
16
- /** Optional custom component to render in the geo section (e.g., WorldMap) */
17
- geoMapComponent?: ReactNode;
18
- /** Show business metrics section (default: true) */
19
- showBusinessMetrics?: boolean;
20
- }
21
- export declare function AnalyticsTab({ isDark, apiBasePath, geoMapComponent, showBusinessMetrics, }: AnalyticsTabProps): import("react/jsx-runtime").JSX.Element | null;
22
- export default AnalyticsTab;
@@ -1,167 +0,0 @@
1
- "use strict";
2
- /**
3
- * =============================================================================
4
- * VIBE ADMIN ANALYTICS TAB
5
- * =============================================================================
6
- *
7
- * Generic dashboard tab showing login statistics and analytics.
8
- * Can be extended by consumer apps with custom components.
9
- *
10
- * =============================================================================
11
- */
12
- 'use client';
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.AnalyticsTab = AnalyticsTab;
15
- const jsx_runtime_1 = require("react/jsx-runtime");
16
- const react_1 = require("react");
17
- // -----------------------------------------------------------------------------
18
- // COMPONENT
19
- // -----------------------------------------------------------------------------
20
- function AnalyticsTab({ isDark = true, apiBasePath = '/api/admin/analytics', geoMapComponent, showBusinessMetrics = true, }) {
21
- const [period, setPeriod] = (0, react_1.useState)('week');
22
- const [data, setData] = (0, react_1.useState)(null);
23
- const [loading, setLoading] = (0, react_1.useState)(true);
24
- const [error, setError] = (0, react_1.useState)(null);
25
- // Business metrics data
26
- const [tierData, setTierData] = (0, react_1.useState)(null);
27
- const [featureData, setFeatureData] = (0, react_1.useState)(null);
28
- const [revenueData, setRevenueData] = (0, react_1.useState)(null);
29
- const themeClasses = {
30
- cardBg: isDark ? 'bg-slate-800 border-slate-700' : 'bg-white border-gray-200 shadow-sm',
31
- textPrimary: isDark ? 'text-white' : 'text-gray-900',
32
- textSecondary: isDark ? 'text-gray-400' : 'text-gray-600',
33
- textMuted: isDark ? 'text-gray-500' : 'text-gray-500',
34
- barBg: isDark ? 'bg-slate-700' : 'bg-gray-200',
35
- };
36
- const fetchAnalytics = (0, react_1.useCallback)(async () => {
37
- setLoading(true);
38
- setError(null);
39
- try {
40
- const res = await fetch(`${apiBasePath}/logins?period=${period}`);
41
- if (!res.ok)
42
- throw new Error('Failed to fetch analytics');
43
- const json = await res.json();
44
- setData(json);
45
- }
46
- catch (err) {
47
- setError(err.message);
48
- }
49
- finally {
50
- setLoading(false);
51
- }
52
- }, [period, apiBasePath]);
53
- // Fetch tier, feature, and revenue data
54
- const fetchBusinessMetrics = (0, react_1.useCallback)(async () => {
55
- if (!showBusinessMetrics)
56
- return;
57
- try {
58
- const [tierRes, featureRes, revenueRes] = await Promise.all([
59
- fetch(`${apiBasePath}/tiers`),
60
- fetch(`${apiBasePath}/feature-usage`),
61
- fetch(`${apiBasePath}/revenue`),
62
- ]);
63
- if (tierRes.ok) {
64
- const data = await tierRes.json();
65
- setTierData(data);
66
- }
67
- if (featureRes.ok) {
68
- const data = await featureRes.json();
69
- setFeatureData(data);
70
- }
71
- if (revenueRes.ok) {
72
- const data = await revenueRes.json();
73
- setRevenueData(data);
74
- }
75
- }
76
- catch (err) {
77
- console.error('Failed to fetch business metrics:', err);
78
- }
79
- }, [apiBasePath, showBusinessMetrics]);
80
- (0, react_1.useEffect)(() => {
81
- fetchAnalytics();
82
- fetchBusinessMetrics();
83
- }, [fetchAnalytics, fetchBusinessMetrics]);
84
- const formatDate = (dateString) => {
85
- return new Date(dateString).toLocaleDateString('en-US', {
86
- month: 'short',
87
- day: 'numeric',
88
- hour: '2-digit',
89
- minute: '2-digit',
90
- });
91
- };
92
- // Simple bar chart component
93
- const BarChart = ({ data, maxValue, colorClass = 'bg-blue-500' }) => ((0, jsx_runtime_1.jsx)("div", { className: "space-y-2", children: data.map((item, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("span", { className: `text-xs ${themeClasses.textSecondary} w-20 truncate`, children: item.label }), (0, jsx_runtime_1.jsx)("div", { className: `flex-1 h-6 ${themeClasses.barBg} rounded overflow-hidden`, children: (0, jsx_runtime_1.jsx)("div", { className: `h-full ${colorClass} transition-all duration-300`, style: { width: `${maxValue > 0 ? (item.value / maxValue) * 100 : 0}%` } }) }), (0, jsx_runtime_1.jsx)("span", { className: `text-xs ${themeClasses.textPrimary} w-12 text-right`, children: item.value })] }, i))) }));
94
- // Time series line chart (simplified as bar chart)
95
- const TimeSeriesChart = ({ series }) => {
96
- const maxCount = Math.max(...series.map(s => s.count), 1);
97
- return ((0, jsx_runtime_1.jsx)("div", { className: "h-48 flex items-end gap-1", children: series.map((item, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex-1 flex flex-col items-center group relative", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-full bg-blue-500 rounded-t transition-all duration-300 hover:bg-blue-400", style: { height: `${(item.count / maxCount) * 100}%`, minHeight: item.count > 0 ? '4px' : '0' } }), (0, jsx_runtime_1.jsx)("div", { className: "absolute bottom-full mb-2 hidden group-hover:block z-10", children: (0, jsx_runtime_1.jsxs)("div", { className: `${isDark ? 'bg-slate-900' : 'bg-gray-800'} text-white text-xs px-2 py-1 rounded shadow-lg whitespace-nowrap`, children: [item.label, ": ", item.count] }) })] }, i))) }));
98
- };
99
- if (loading && !data) {
100
- return ((0, jsx_runtime_1.jsx)("div", { className: "flex items-center justify-center py-12", children: (0, jsx_runtime_1.jsxs)("svg", { className: "animate-spin h-8 w-8 text-blue-400", viewBox: "0 0 24 24", fill: "none", children: [(0, jsx_runtime_1.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), (0, jsx_runtime_1.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8v4a4 4 0 00-4 4H4z" })] }) }));
101
- }
102
- if (error) {
103
- return ((0, jsx_runtime_1.jsxs)("div", { className: `${isDark ? 'bg-red-900/30 border-red-700' : 'bg-red-50 border-red-300'} border rounded-lg p-4 ${isDark ? 'text-red-300' : 'text-red-700'}`, children: [error, (0, jsx_runtime_1.jsx)("button", { onClick: fetchAnalytics, className: "ml-4 underline", children: "Retry" })] }));
104
- }
105
- if (!data)
106
- return null;
107
- const deviceData = Object.entries(data.byDevice)
108
- .map(([label, value]) => ({ label: label.charAt(0).toUpperCase() + label.slice(1), value }))
109
- .sort((a, b) => b.value - a.value);
110
- const browserData = Object.entries(data.byBrowser)
111
- .map(([label, value]) => ({ label, value }))
112
- .sort((a, b) => b.value - a.value)
113
- .slice(0, 5);
114
- const osData = Object.entries(data.byOS)
115
- .map(([label, value]) => ({ label, value }))
116
- .sort((a, b) => b.value - a.value)
117
- .slice(0, 5);
118
- return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsx)("div", { className: "flex gap-2", children: ['today', 'week', 'month', 'year'].map((p) => ((0, jsx_runtime_1.jsx)("button", { onClick: () => setPeriod(p), className: `px-4 py-2 rounded-lg text-sm font-medium transition-colors ${period === p
119
- ? 'bg-blue-600 text-white'
120
- : isDark ? 'bg-slate-700 text-gray-300 hover:bg-slate-600' : 'bg-gray-200 text-gray-700 hover:bg-gray-300'}`, children: p === 'today' ? 'Today' : p === 'week' ? 'This Week' : p === 'month' ? 'This Month' : 'This Year' }, p))) }), (0, jsx_runtime_1.jsx)("button", { onClick: fetchAnalytics, disabled: loading, className: `p-2 ${themeClasses.textSecondary} hover:${themeClasses.textPrimary} transition-colors disabled:opacity-50`, title: "Refresh", children: (0, jsx_runtime_1.jsx)("svg", { className: `w-5 h-5 ${loading ? 'animate-spin' : ''}`, fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: (0, jsx_runtime_1.jsx)("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) }) })] }), (0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-5 gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-4`, children: [(0, jsx_runtime_1.jsx)("p", { className: themeClasses.textSecondary + ' text-sm', children: "Total Logins" }), (0, jsx_runtime_1.jsx)("p", { className: `text-3xl font-bold ${themeClasses.textPrimary}`, children: data.summary.totalLogins.toLocaleString() })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-4`, children: [(0, jsx_runtime_1.jsx)("p", { className: themeClasses.textSecondary + ' text-sm', children: "Unique Users" }), (0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-blue-400", children: data.summary.uniqueUsers.toLocaleString() })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-4`, children: [(0, jsx_runtime_1.jsx)("p", { className: themeClasses.textSecondary + ' text-sm', children: "New Users" }), (0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-green-400", children: data.summary.newUsers.toLocaleString() })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-4`, children: [(0, jsx_runtime_1.jsx)("p", { className: themeClasses.textSecondary + ' text-sm', children: "Peak Hour" }), (0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-purple-400", children: data.summary.peakHour })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-4`, children: [(0, jsx_runtime_1.jsx)("p", { className: themeClasses.textSecondary + ' text-sm', children: "Avg/Day" }), (0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-orange-400", children: data.summary.avgLoginsPerDay.toLocaleString() })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-6`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary} mb-4`, children: "Logins Over Time" }), (0, jsx_runtime_1.jsx)(TimeSeriesChart, { series: data.timeSeries }), (0, jsx_runtime_1.jsxs)("div", { className: `flex justify-between mt-2 text-xs ${themeClasses.textMuted}`, children: [(0, jsx_runtime_1.jsx)("span", { children: data.timeSeries[0]?.label }), (0, jsx_runtime_1.jsx)("span", { children: data.timeSeries[data.timeSeries.length - 1]?.label })] })] }), geoMapComponent && ((0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-6`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary} mb-4`, children: "Geographic Distribution" }), geoMapComponent] })), (0, jsx_runtime_1.jsxs)("div", { className: "grid md:grid-cols-2 gap-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-6`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary} mb-4`, children: "Top Countries" }), data.byCountry.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: data.byCountry.slice(0, 8).map((country, i) => ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xl", children: country.flag }), (0, jsx_runtime_1.jsx)("span", { className: `${themeClasses.textPrimary} flex-1`, children: country.country }), (0, jsx_runtime_1.jsx)("div", { className: `w-24 h-4 ${themeClasses.barBg} rounded overflow-hidden`, children: (0, jsx_runtime_1.jsx)("div", { className: "h-full bg-green-500", style: { width: `${country.percentage}%` } }) }), (0, jsx_runtime_1.jsxs)("span", { className: `${themeClasses.textSecondary} text-sm w-16 text-right`, children: [country.count, " (", country.percentage, "%)"] })] }, i))) })) : ((0, jsx_runtime_1.jsx)("p", { className: `${themeClasses.textMuted} text-center py-4`, children: "No data" }))] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-6`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary} mb-4`, children: "Device Types" }), deviceData.length > 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "space-y-4", children: deviceData.map((item, i) => {
121
- const total = deviceData.reduce((sum, d) => sum + d.value, 0);
122
- const percentage = total > 0 ? Math.round((item.value / total) * 100) : 0;
123
- const icon = item.label.toLowerCase() === 'mobile' ? '📱' :
124
- item.label.toLowerCase() === 'tablet' ? '📱' : '💻';
125
- return ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)("span", { className: "text-xl", children: icon }), (0, jsx_runtime_1.jsx)("span", { className: `${themeClasses.textPrimary} w-20`, children: item.label }), (0, jsx_runtime_1.jsx)("div", { className: `flex-1 h-6 ${themeClasses.barBg} rounded overflow-hidden`, children: (0, jsx_runtime_1.jsx)("div", { className: "h-full bg-purple-500", style: { width: `${percentage}%` } }) }), (0, jsx_runtime_1.jsxs)("span", { className: `${themeClasses.textSecondary} text-sm w-20 text-right`, children: [item.value, " (", percentage, "%)"] })] }, i));
126
- }) })) : ((0, jsx_runtime_1.jsx)("p", { className: `${themeClasses.textMuted} text-center py-4`, children: "No data" }))] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-6`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary} mb-4`, children: "Browsers" }), (0, jsx_runtime_1.jsx)(BarChart, { data: browserData, maxValue: Math.max(...browserData.map(d => d.value), 1), colorClass: "bg-orange-500" })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-6`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary} mb-4`, children: "Operating Systems" }), (0, jsx_runtime_1.jsx)(BarChart, { data: osData, maxValue: Math.max(...osData.map(d => d.value), 1), colorClass: "bg-cyan-500" })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg overflow-hidden`, children: [(0, jsx_runtime_1.jsx)("div", { className: `p-4 border-b ${isDark ? 'border-slate-700' : 'border-gray-200'}`, children: (0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary}`, children: "Top Users by Login Count" }) }), (0, jsx_runtime_1.jsx)("div", { className: "overflow-x-auto", children: (0, jsx_runtime_1.jsxs)("table", { className: "w-full text-sm", children: [(0, jsx_runtime_1.jsx)("thead", { className: isDark ? 'bg-slate-700/50' : 'bg-gray-50', children: (0, jsx_runtime_1.jsxs)("tr", { children: [(0, jsx_runtime_1.jsx)("th", { className: `px-4 py-3 text-left ${themeClasses.textSecondary} font-medium`, children: "#" }), (0, jsx_runtime_1.jsx)("th", { className: `px-4 py-3 text-left ${themeClasses.textSecondary} font-medium`, children: "User" }), (0, jsx_runtime_1.jsx)("th", { className: `px-4 py-3 text-left ${themeClasses.textSecondary} font-medium`, children: "Logins" }), (0, jsx_runtime_1.jsx)("th", { className: `px-4 py-3 text-left ${themeClasses.textSecondary} font-medium`, children: "Last Login" })] }) }), (0, jsx_runtime_1.jsx)("tbody", { className: `divide-y ${isDark ? 'divide-slate-700' : 'divide-gray-200'}`, children: data.topUsers.length > 0 ? (data.topUsers.map((user, i) => ((0, jsx_runtime_1.jsxs)("tr", { className: isDark ? 'hover:bg-slate-700/50' : 'hover:bg-gray-50', children: [(0, jsx_runtime_1.jsx)("td", { className: `px-4 py-3 ${themeClasses.textMuted}`, children: i + 1 }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("p", { className: `${themeClasses.textPrimary} font-medium`, children: user.name }), (0, jsx_runtime_1.jsx)("p", { className: `${themeClasses.textSecondary} text-xs`, children: user.email })] }) }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsx)("span", { className: "px-2 py-1 bg-blue-600/20 text-blue-400 rounded text-xs font-medium", children: user.count }) }), (0, jsx_runtime_1.jsx)("td", { className: `px-4 py-3 ${themeClasses.textSecondary}`, children: formatDate(user.lastLogin) })] }, i)))) : ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", { colSpan: 4, className: `px-4 py-8 text-center ${themeClasses.textMuted}`, children: "No login data for this period" }) })) })] }) })] }), showBusinessMetrics && ((0, jsx_runtime_1.jsxs)("div", { className: `border-t ${isDark ? 'border-slate-700' : 'border-gray-200'} pt-6 mt-6`, children: [(0, jsx_runtime_1.jsx)("h2", { className: `text-xl font-bold ${themeClasses.textPrimary} mb-6`, children: "Business Metrics" }), revenueData && ((0, jsx_runtime_1.jsxs)("div", { className: "grid grid-cols-2 md:grid-cols-4 gap-4 mb-6", children: [(0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-4`, children: [(0, jsx_runtime_1.jsx)("p", { className: themeClasses.textSecondary + ' text-sm', children: "Monthly Revenue (MRR)" }), (0, jsx_runtime_1.jsxs)("p", { className: "text-3xl font-bold text-green-400", children: ["$", revenueData.mrr.toLocaleString()] })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-4`, children: [(0, jsx_runtime_1.jsx)("p", { className: themeClasses.textSecondary + ' text-sm', children: "Annual Revenue (ARR)" }), (0, jsx_runtime_1.jsxs)("p", { className: "text-3xl font-bold text-green-400", children: ["$", revenueData.arr.toLocaleString()] })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-4`, children: [(0, jsx_runtime_1.jsx)("p", { className: themeClasses.textSecondary + ' text-sm', children: "Paid Subscribers" }), (0, jsx_runtime_1.jsx)("p", { className: "text-3xl font-bold text-blue-400", children: revenueData.paidSubscribers.toLocaleString() })] }), (0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-4`, children: [(0, jsx_runtime_1.jsx)("p", { className: themeClasses.textSecondary + ' text-sm', children: "Conversion Rate" }), (0, jsx_runtime_1.jsxs)("p", { className: "text-3xl font-bold text-purple-400", children: [revenueData.conversionRate, "%"] })] })] })), (0, jsx_runtime_1.jsxs)("div", { className: "grid md:grid-cols-2 gap-6", children: [tierData && ((0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-6`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary} mb-4`, children: "Tier Distribution" }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-8", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative w-40 h-40", children: [(0, jsx_runtime_1.jsx)("svg", { viewBox: "0 0 100 100", className: "transform -rotate-90", children: (() => {
127
- const colors = {
128
- free: '#64748b',
129
- premium: '#3b82f6',
130
- ultimate: '#f59e0b',
131
- enterprise: '#8b5cf6',
132
- };
133
- let offset = 0;
134
- return tierData.distribution.map((tier) => {
135
- const strokeDasharray = `${tier.percentage} ${100 - tier.percentage}`;
136
- const strokeDashoffset = -offset;
137
- offset += tier.percentage;
138
- return ((0, jsx_runtime_1.jsx)("circle", { cx: "50", cy: "50", r: "40", fill: "transparent", stroke: colors[tier.tier] || '#64748b', strokeWidth: "20", strokeDasharray: strokeDasharray, strokeDashoffset: strokeDashoffset }, tier.tier));
139
- });
140
- })() }), (0, jsx_runtime_1.jsx)("div", { className: "absolute inset-0 flex items-center justify-center", children: (0, jsx_runtime_1.jsxs)("div", { className: "text-center", children: [(0, jsx_runtime_1.jsx)("p", { className: `text-2xl font-bold ${themeClasses.textPrimary}`, children: tierData.total }), (0, jsx_runtime_1.jsx)("p", { className: `text-xs ${themeClasses.textSecondary}`, children: "Total" })] }) })] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 space-y-2", children: tierData.distribution.map((tier) => {
141
- const colors = {
142
- free: 'bg-slate-500',
143
- premium: 'bg-blue-500',
144
- ultimate: 'bg-amber-500',
145
- enterprise: 'bg-purple-500',
146
- };
147
- return ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: `w-3 h-3 rounded-full ${colors[tier.tier] || 'bg-slate-500'}` }), (0, jsx_runtime_1.jsx)("span", { className: `${themeClasses.textPrimary} capitalize`, children: tier.tier })] }), (0, jsx_runtime_1.jsxs)("div", { className: "text-right", children: [(0, jsx_runtime_1.jsx)("span", { className: `${themeClasses.textPrimary} font-medium`, children: tier.count }), (0, jsx_runtime_1.jsxs)("span", { className: `${themeClasses.textMuted} text-sm ml-2`, children: ["(", tier.percentage, "%)"] })] })] }, tier.tier));
148
- }) })] })] })), featureData && ((0, jsx_runtime_1.jsxs)("div", { className: `${themeClasses.cardBg} border rounded-lg p-6`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary} mb-4`, children: "Feature Usage" }), (0, jsx_runtime_1.jsx)("div", { className: "space-y-3", children: featureData.features.map((feature) => {
149
- const maxUses = Math.max(...featureData.features.map(f => f.uses), 1);
150
- const percentage = (feature.uses / maxUses) * 100;
151
- return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex justify-between items-center mb-1", children: [(0, jsx_runtime_1.jsx)("span", { className: `${themeClasses.textPrimary} text-sm`, children: feature.name }), (0, jsx_runtime_1.jsxs)("span", { className: `${themeClasses.textSecondary} text-xs`, children: [feature.uses.toLocaleString(), " uses"] })] }), (0, jsx_runtime_1.jsx)("div", { className: `h-4 ${themeClasses.barBg} rounded overflow-hidden`, children: (0, jsx_runtime_1.jsx)("div", { className: "h-full bg-gradient-to-r from-indigo-500 to-purple-500 transition-all duration-300", style: { width: `${percentage}%` } }) })] }, feature.name));
152
- }) })] }))] }), revenueData && revenueData.revenueByTier.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: `mt-6 ${themeClasses.cardBg} border rounded-lg overflow-hidden`, children: [(0, jsx_runtime_1.jsx)("div", { className: `p-4 border-b ${isDark ? 'border-slate-700' : 'border-gray-200'}`, children: (0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary}`, children: "Revenue by Tier" }) }), (0, jsx_runtime_1.jsx)("div", { className: "overflow-x-auto", children: (0, jsx_runtime_1.jsxs)("table", { className: "w-full text-sm", children: [(0, jsx_runtime_1.jsx)("thead", { className: isDark ? 'bg-slate-700/50' : 'bg-gray-50', children: (0, jsx_runtime_1.jsxs)("tr", { children: [(0, jsx_runtime_1.jsx)("th", { className: `px-4 py-3 text-left ${themeClasses.textSecondary} font-medium`, children: "Tier" }), (0, jsx_runtime_1.jsx)("th", { className: `px-4 py-3 text-left ${themeClasses.textSecondary} font-medium`, children: "Subscribers" }), (0, jsx_runtime_1.jsx)("th", { className: `px-4 py-3 text-left ${themeClasses.textSecondary} font-medium`, children: "Price/Mo" }), (0, jsx_runtime_1.jsx)("th", { className: `px-4 py-3 text-left ${themeClasses.textSecondary} font-medium`, children: "MRR" }), (0, jsx_runtime_1.jsx)("th", { className: `px-4 py-3 text-left ${themeClasses.textSecondary} font-medium`, children: "% of Revenue" })] }) }), (0, jsx_runtime_1.jsx)("tbody", { className: `divide-y ${isDark ? 'divide-slate-700' : 'divide-gray-200'}`, children: revenueData.revenueByTier.map((tier) => {
153
- const totalMrr = revenueData.revenueByTier.reduce((sum, t) => sum + t.mrr, 0);
154
- const percentage = totalMrr > 0 ? Math.round((tier.mrr / totalMrr) * 100) : 0;
155
- const tierColors = {
156
- premium: 'text-blue-400',
157
- ultimate: 'text-amber-400',
158
- enterprise: 'text-purple-400',
159
- };
160
- return ((0, jsx_runtime_1.jsxs)("tr", { className: isDark ? 'hover:bg-slate-700/50' : 'hover:bg-gray-50', children: [(0, jsx_runtime_1.jsx)("td", { className: `px-4 py-3 font-medium capitalize ${tierColors[tier.tier] || themeClasses.textPrimary}`, children: tier.tier }), (0, jsx_runtime_1.jsx)("td", { className: `px-4 py-3 ${themeClasses.textPrimary}`, children: tier.subscribers.toLocaleString() }), (0, jsx_runtime_1.jsxs)("td", { className: `px-4 py-3 ${themeClasses.textSecondary}`, children: ["$", tier.pricePerMonth] }), (0, jsx_runtime_1.jsxs)("td", { className: "px-4 py-3 text-green-400 font-medium", children: ["$", tier.mrr.toLocaleString()] }), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-3", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsx)("div", { className: `w-16 h-2 ${themeClasses.barBg} rounded overflow-hidden`, children: (0, jsx_runtime_1.jsx)("div", { className: "h-full bg-green-500", style: { width: `${percentage}%` } }) }), (0, jsx_runtime_1.jsxs)("span", { className: `${themeClasses.textSecondary} text-xs`, children: [percentage, "%"] })] }) })] }, tier.tier));
161
- }) })] }) })] })), revenueData && revenueData.trend.length > 0 && ((0, jsx_runtime_1.jsxs)("div", { className: `mt-6 ${themeClasses.cardBg} border rounded-lg p-6`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `text-lg font-semibold ${themeClasses.textPrimary} mb-4`, children: "MRR Trend (6 Months)" }), (0, jsx_runtime_1.jsx)("div", { className: "h-48 flex items-end gap-2", children: revenueData.trend.map((point, i) => {
162
- const maxMrr = Math.max(...revenueData.trend.map(p => p.mrr), 1);
163
- const height = (point.mrr / maxMrr) * 100;
164
- return ((0, jsx_runtime_1.jsxs)("div", { className: "flex-1 flex flex-col items-center group", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative w-full", children: [(0, jsx_runtime_1.jsx)("div", { className: "w-full bg-gradient-to-t from-green-600 to-green-400 rounded-t transition-all duration-300 hover:from-green-500 hover:to-green-300", style: { height: `${height * 1.8}px`, minHeight: '4px' } }), (0, jsx_runtime_1.jsx)("div", { className: "absolute bottom-full mb-2 left-1/2 -translate-x-1/2 hidden group-hover:block z-10", children: (0, jsx_runtime_1.jsxs)("div", { className: `${isDark ? 'bg-slate-900' : 'bg-gray-800'} text-white text-xs px-2 py-1 rounded shadow-lg whitespace-nowrap`, children: ["$", point.mrr.toLocaleString()] }) })] }), (0, jsx_runtime_1.jsx)("span", { className: `text-xs ${themeClasses.textMuted} mt-2`, children: point.month })] }, i));
165
- }) })] }))] }))] }));
166
- }
167
- exports.default = AnalyticsTab;
@@ -1,19 +0,0 @@
1
- export interface CollectionInfo {
2
- name: string;
3
- tableCount: number;
4
- }
5
- export interface TableInfo {
6
- name: string;
7
- count: number;
8
- }
9
- export interface DataBrowserTabProps {
10
- isDark?: boolean;
11
- /** Base API path for admin vibe data (default: /api/admin/vibe) */
12
- apiBasePath?: string;
13
- /** Collection to focus on (optional - shows all if not specified) */
14
- focusCollection?: string;
15
- /** Title for the data browser */
16
- title?: string;
17
- }
18
- export declare function DataBrowserTab({ isDark, apiBasePath, focusCollection, title, }: DataBrowserTabProps): import("react/jsx-runtime").JSX.Element;
19
- export default DataBrowserTab;
@@ -1,252 +0,0 @@
1
- "use strict";
2
- 'use client';
3
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = { enumerable: true, get: function() { return m[k]; } };
8
- }
9
- Object.defineProperty(o, k2, desc);
10
- }) : (function(o, m, k, k2) {
11
- if (k2 === undefined) k2 = k;
12
- o[k2] = m[k];
13
- }));
14
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
15
- Object.defineProperty(o, "default", { enumerable: true, value: v });
16
- }) : function(o, v) {
17
- o["default"] = v;
18
- });
19
- var __importStar = (this && this.__importStar) || (function () {
20
- var ownKeys = function(o) {
21
- ownKeys = Object.getOwnPropertyNames || function (o) {
22
- var ar = [];
23
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
24
- return ar;
25
- };
26
- return ownKeys(o);
27
- };
28
- return function (mod) {
29
- if (mod && mod.__esModule) return mod;
30
- var result = {};
31
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
32
- __setModuleDefault(result, mod);
33
- return result;
34
- };
35
- })();
36
- Object.defineProperty(exports, "__esModule", { value: true });
37
- exports.DataBrowserTab = DataBrowserTab;
38
- const jsx_runtime_1 = require("react/jsx-runtime");
39
- const react_1 = __importStar(require("react"));
40
- const lucide_react_1 = require("lucide-react");
41
- // -----------------------------------------------------------------------------
42
- // COMPONENT
43
- // -----------------------------------------------------------------------------
44
- function DataBrowserTab({ isDark = true, apiBasePath = '/api/admin/vibe', focusCollection, title = 'Data Browser', }) {
45
- // Collections state
46
- const [collections, setCollections] = (0, react_1.useState)([]);
47
- const [loadingCollections, setLoadingCollections] = (0, react_1.useState)(true);
48
- const [expandedCollections, setExpandedCollections] = (0, react_1.useState)(new Set());
49
- // Selection state
50
- const [selectedCollection, setSelectedCollection] = (0, react_1.useState)(focusCollection || null);
51
- const [selectedTable, setSelectedTable] = (0, react_1.useState)(null);
52
- // Table data state
53
- const [tableData, setTableData] = (0, react_1.useState)(null);
54
- const [loadingData, setLoadingData] = (0, react_1.useState)(false);
55
- const [expandedRow, setExpandedRow] = (0, react_1.useState)(null);
56
- const [searchTerm, setSearchTerm] = (0, react_1.useState)('');
57
- // Messages
58
- const [error, setError] = (0, react_1.useState)(null);
59
- const [success, setSuccess] = (0, react_1.useState)(null);
60
- // Track rows being deleted
61
- const [deletingRows, setDeletingRows] = (0, react_1.useState)(new Set());
62
- const themeClasses = {
63
- cardBg: isDark ? 'bg-slate-800 border-slate-700' : 'bg-white border-gray-200 shadow-sm',
64
- inputBg: isDark ? 'bg-slate-900 border-slate-600 text-white placeholder-gray-500' : 'bg-white border-gray-300 text-gray-900 placeholder-gray-400',
65
- textPrimary: isDark ? 'text-white' : 'text-gray-900',
66
- textSecondary: isDark ? 'text-gray-400' : 'text-gray-600',
67
- textMuted: isDark ? 'text-gray-500' : 'text-gray-500',
68
- hoverBg: isDark ? 'hover:bg-slate-700' : 'hover:bg-gray-50',
69
- tableBg: isDark ? 'bg-slate-900' : 'bg-gray-50',
70
- tableHeader: isDark ? 'bg-slate-800 text-gray-300' : 'bg-gray-100 text-gray-700',
71
- tableRow: isDark ? 'border-slate-700 hover:bg-slate-800' : 'border-gray-200 hover:bg-gray-50',
72
- };
73
- // Fetch collections
74
- const fetchCollections = (0, react_1.useCallback)(async () => {
75
- setLoadingCollections(true);
76
- setError(null);
77
- try {
78
- const response = await fetch(`${apiBasePath}/collections`);
79
- if (!response.ok)
80
- throw new Error('Failed to fetch collections');
81
- const data = await response.json();
82
- const rawCollections = Array.isArray(data) ? data
83
- : Array.isArray(data.collections) ? data.collections
84
- : Array.isArray(data.data) ? data.data
85
- : [];
86
- const collectionList = rawCollections.map((c) => ({
87
- name: typeof c === 'string' ? c : c.name,
88
- tableCount: typeof c === 'object' ? (c.table_count || c.tableCount || 0) : 0,
89
- tables: [],
90
- loadingTables: false,
91
- }));
92
- // If focusCollection is set, filter to just that collection
93
- const filteredList = focusCollection
94
- ? collectionList.filter(c => c.name === focusCollection)
95
- : collectionList;
96
- setCollections(filteredList);
97
- // Auto-expand first collection
98
- if (filteredList.length > 0) {
99
- const firstName = filteredList[0].name;
100
- setExpandedCollections(new Set([firstName]));
101
- fetchTablesForCollection(firstName);
102
- }
103
- }
104
- catch (err) {
105
- console.error('Failed to fetch collections:', err);
106
- setError('Failed to fetch collections');
107
- setCollections([]);
108
- }
109
- finally {
110
- setLoadingCollections(false);
111
- }
112
- }, [apiBasePath, focusCollection]);
113
- // Fetch tables for a collection
114
- const fetchTablesForCollection = (0, react_1.useCallback)(async (collectionName) => {
115
- setCollections(prev => prev.map(c => c.name === collectionName ? { ...c, loadingTables: true } : c));
116
- try {
117
- const response = await fetch(`${apiBasePath}/collections/${collectionName}/tables`);
118
- if (!response.ok)
119
- throw new Error('Failed to fetch tables');
120
- const data = await response.json();
121
- const rawTables = Array.isArray(data) ? data
122
- : Array.isArray(data.tables) ? data.tables
123
- : Array.isArray(data.data) ? data.data
124
- : [];
125
- const tableList = rawTables.map((t) => ({
126
- name: typeof t === 'string' ? t : t.name,
127
- count: typeof t === 'object' ? (t.document_count || t.count || 0) : 0,
128
- }));
129
- setCollections(prev => prev.map(c => c.name === collectionName ? { ...c, tables: tableList, loadingTables: false } : c));
130
- }
131
- catch (err) {
132
- console.error(`Failed to fetch tables for ${collectionName}:`, err);
133
- setCollections(prev => prev.map(c => c.name === collectionName ? { ...c, loadingTables: false } : c));
134
- }
135
- }, [apiBasePath]);
136
- // Fetch table data
137
- const fetchTableData = (0, react_1.useCallback)(async (collection, table) => {
138
- setLoadingData(true);
139
- setError(null);
140
- setExpandedRow(null);
141
- try {
142
- const response = await fetch(`${apiBasePath}/data/${collection}/${table}?limit=50`);
143
- if (!response.ok)
144
- throw new Error('Failed to fetch data');
145
- const data = await response.json();
146
- const records = Array.isArray(data) ? data
147
- : Array.isArray(data.data) ? data.data
148
- : Array.isArray(data.documents) ? data.documents
149
- : [];
150
- setTableData({
151
- data: records,
152
- meta: data.meta || { total: records.length, limit: 50, offset: 0 },
153
- });
154
- }
155
- catch (err) {
156
- console.error(`Failed to fetch data for ${collection}/${table}:`, err);
157
- setError(`Failed to fetch data: ${err}`);
158
- setTableData(null);
159
- }
160
- finally {
161
- setLoadingData(false);
162
- }
163
- }, [apiBasePath]);
164
- // Delete record
165
- const handleDelete = (0, react_1.useCallback)(async (id) => {
166
- if (!selectedCollection || !selectedTable)
167
- return;
168
- if (!confirm(`Delete record ${id}?`))
169
- return;
170
- setDeletingRows(prev => new Set(prev).add(id));
171
- try {
172
- const response = await fetch(`${apiBasePath}/data/${selectedCollection}/${selectedTable}/${id}`, {
173
- method: 'DELETE',
174
- });
175
- if (!response.ok) {
176
- const errData = await response.json().catch(() => ({}));
177
- throw new Error(errData.error?.message || 'Delete failed');
178
- }
179
- setSuccess(`Record ${id} deleted`);
180
- setTimeout(() => setSuccess(null), 3000);
181
- // Remove from local state
182
- setTableData(prev => prev ? {
183
- ...prev,
184
- data: prev.data.filter(row => (row.id || row.document_id) !== id),
185
- } : null);
186
- }
187
- catch (err) {
188
- setError(`Failed to delete: ${err}`);
189
- }
190
- finally {
191
- setDeletingRows(prev => {
192
- const next = new Set(prev);
193
- next.delete(id);
194
- return next;
195
- });
196
- }
197
- }, [selectedCollection, selectedTable, apiBasePath]);
198
- // Toggle collection expansion
199
- const toggleCollection = (name) => {
200
- setExpandedCollections(prev => {
201
- const next = new Set(prev);
202
- if (next.has(name)) {
203
- next.delete(name);
204
- }
205
- else {
206
- next.add(name);
207
- // Fetch tables if not loaded
208
- const coll = collections.find(c => c.name === name);
209
- if (coll && coll.tables.length === 0 && !coll.loadingTables) {
210
- fetchTablesForCollection(name);
211
- }
212
- }
213
- return next;
214
- });
215
- };
216
- // Select table
217
- const selectTable = (collection, table) => {
218
- setSelectedCollection(collection);
219
- setSelectedTable(table);
220
- fetchTableData(collection, table);
221
- };
222
- // Initial load
223
- (0, react_1.useEffect)(() => {
224
- fetchCollections();
225
- }, [fetchCollections]);
226
- // Get columns from data
227
- const getColumns = () => {
228
- if (!tableData?.data?.length)
229
- return [];
230
- const firstRow = tableData.data[0];
231
- return Object.keys(firstRow).filter(k => !['data', '__metadata'].includes(k));
232
- };
233
- // Filter data by search term
234
- const filteredData = tableData?.data?.filter(row => {
235
- if (!searchTerm)
236
- return true;
237
- const searchLower = searchTerm.toLowerCase();
238
- return Object.values(row).some(val => String(val).toLowerCase().includes(searchLower));
239
- }) || [];
240
- const columns = getColumns();
241
- return ((0, jsx_runtime_1.jsxs)("div", { className: "space-y-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-between", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-3", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Database, { className: `w-6 h-6 ${isDark ? 'text-indigo-400' : 'text-indigo-600'}` }), (0, jsx_runtime_1.jsx)("h2", { className: `text-xl font-semibold ${themeClasses.textPrimary}`, children: title })] }), (0, jsx_runtime_1.jsxs)("button", { onClick: fetchCollections, disabled: loadingCollections, className: `flex items-center gap-2 px-3 py-1.5 rounded-lg text-sm ${themeClasses.hoverBg} ${themeClasses.textSecondary}`, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCw, { className: `w-4 h-4 ${loadingCollections ? 'animate-spin' : ''}` }), "Refresh"] })] }), error && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 p-3 bg-red-900/20 border border-red-800 rounded-lg text-red-400", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.AlertCircle, { className: "w-4 h-4" }), error] })), success && ((0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2 p-3 bg-green-900/20 border border-green-800 rounded-lg text-green-400", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.CheckCircle, { className: "w-4 h-4" }), success] })), (0, jsx_runtime_1.jsxs)("div", { className: "flex gap-4", children: [(0, jsx_runtime_1.jsxs)("div", { className: `w-64 flex-shrink-0 rounded-lg border ${themeClasses.cardBg} p-3`, children: [(0, jsx_runtime_1.jsx)("h3", { className: `text-sm font-medium mb-3 ${themeClasses.textSecondary}`, children: "Collections" }), loadingCollections ? ((0, jsx_runtime_1.jsx)("div", { className: `text-sm ${themeClasses.textMuted}`, children: "Loading..." })) : collections.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: `text-sm ${themeClasses.textMuted}`, children: "No collections found" })) : ((0, jsx_runtime_1.jsx)("div", { className: "space-y-1", children: collections.map(coll => ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("button", { onClick: () => toggleCollection(coll.name), className: `w-full flex items-center gap-2 px-2 py-1.5 rounded text-left text-sm ${themeClasses.hoverBg} ${themeClasses.textPrimary}`, children: [expandedCollections.has(coll.name) ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { className: "w-4 h-4" })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronRight, { className: "w-4 h-4" })), (0, jsx_runtime_1.jsx)(lucide_react_1.Database, { className: "w-4 h-4" }), (0, jsx_runtime_1.jsx)("span", { className: "truncate flex-1", children: coll.name }), coll.tableCount > 0 && ((0, jsx_runtime_1.jsx)("span", { className: `text-xs ${themeClasses.textMuted}`, children: coll.tableCount }))] }), expandedCollections.has(coll.name) && ((0, jsx_runtime_1.jsx)("div", { className: "ml-6 mt-1 space-y-0.5", children: coll.loadingTables ? ((0, jsx_runtime_1.jsx)("div", { className: `text-xs px-2 py-1 ${themeClasses.textMuted}`, children: "Loading..." })) : coll.tables.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: `text-xs px-2 py-1 ${themeClasses.textMuted}`, children: "No tables" })) : (coll.tables.map(table => ((0, jsx_runtime_1.jsxs)("button", { onClick: () => selectTable(coll.name, table.name), className: `w-full flex items-center gap-2 px-2 py-1 rounded text-left text-sm ${selectedCollection === coll.name && selectedTable === table.name
242
- ? isDark ? 'bg-indigo-900/50 text-indigo-300' : 'bg-indigo-100 text-indigo-700'
243
- : themeClasses.hoverBg + ' ' + themeClasses.textSecondary}`, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Table2, { className: "w-3 h-3" }), (0, jsx_runtime_1.jsx)("span", { className: "truncate flex-1", children: table.name }), table.count > 0 && ((0, jsx_runtime_1.jsx)("span", { className: `text-xs ${themeClasses.textMuted}`, children: table.count }))] }, table.name)))) }))] }, coll.name))) }))] }), (0, jsx_runtime_1.jsx)("div", { className: "flex-1 min-w-0", children: !selectedTable ? ((0, jsx_runtime_1.jsxs)("div", { className: `rounded-lg border ${themeClasses.cardBg} p-8 text-center`, children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Table2, { className: `w-12 h-12 mx-auto mb-4 ${themeClasses.textMuted}` }), (0, jsx_runtime_1.jsx)("p", { className: themeClasses.textSecondary, children: "Select a table to view data" })] })) : ((0, jsx_runtime_1.jsxs)("div", { className: `rounded-lg border ${themeClasses.cardBg}`, children: [(0, jsx_runtime_1.jsxs)("div", { className: `px-4 py-3 border-b ${isDark ? 'border-slate-700' : 'border-gray-200'} flex items-center justify-between`, children: [(0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsxs)("h3", { className: `font-medium ${themeClasses.textPrimary}`, children: [selectedCollection, " / ", selectedTable] }), (0, jsx_runtime_1.jsxs)("p", { className: `text-sm ${themeClasses.textMuted}`, children: [tableData?.meta?.total || filteredData.length, " records"] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center gap-2", children: [(0, jsx_runtime_1.jsxs)("div", { className: "relative", children: [(0, jsx_runtime_1.jsx)(lucide_react_1.Search, { className: `absolute left-3 top-1/2 -translate-y-1/2 w-4 h-4 ${themeClasses.textMuted}` }), (0, jsx_runtime_1.jsx)("input", { type: "text", placeholder: "Search...", value: searchTerm, onChange: (e) => setSearchTerm(e.target.value), className: `pl-9 pr-3 py-1.5 rounded-lg border text-sm ${themeClasses.inputBg}` })] }), (0, jsx_runtime_1.jsx)("button", { onClick: () => fetchTableData(selectedCollection, selectedTable), disabled: loadingData, className: `p-1.5 rounded-lg ${themeClasses.hoverBg}`, children: (0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCw, { className: `w-4 h-4 ${loadingData ? 'animate-spin' : ''} ${themeClasses.textSecondary}` }) })] })] }), loadingData ? ((0, jsx_runtime_1.jsx)("div", { className: "p-8 text-center", children: (0, jsx_runtime_1.jsx)(lucide_react_1.RefreshCw, { className: `w-8 h-8 mx-auto animate-spin ${themeClasses.textMuted}` }) })) : filteredData.length === 0 ? ((0, jsx_runtime_1.jsx)("div", { className: "p-8 text-center", children: (0, jsx_runtime_1.jsx)("p", { className: themeClasses.textMuted, children: "No records found" }) })) : ((0, jsx_runtime_1.jsx)("div", { className: "overflow-x-auto", children: (0, jsx_runtime_1.jsxs)("table", { className: "w-full text-sm", children: [(0, jsx_runtime_1.jsx)("thead", { children: (0, jsx_runtime_1.jsxs)("tr", { className: themeClasses.tableHeader, children: [columns.slice(0, 6).map(col => ((0, jsx_runtime_1.jsx)("th", { className: "px-4 py-2 text-left font-medium", children: col }, col))), (0, jsx_runtime_1.jsx)("th", { className: "px-4 py-2 text-right", children: "Actions" })] }) }), (0, jsx_runtime_1.jsx)("tbody", { children: filteredData.map((row, idx) => {
244
- const rowId = row.id || row.document_id || idx;
245
- const isExpanded = expandedRow === rowId;
246
- const isDeleting = deletingRows.has(rowId);
247
- return ((0, jsx_runtime_1.jsxs)(react_1.default.Fragment, { children: [(0, jsx_runtime_1.jsxs)("tr", { className: `border-t ${themeClasses.tableRow} ${isDeleting ? 'opacity-50' : ''}`, children: [columns.slice(0, 6).map(col => ((0, jsx_runtime_1.jsx)("td", { className: `px-4 py-2 ${themeClasses.textPrimary}`, children: (0, jsx_runtime_1.jsx)("div", { className: "max-w-xs truncate", children: typeof row[col] === 'object'
248
- ? JSON.stringify(row[col]).slice(0, 50)
249
- : String(row[col] ?? '') }) }, col))), (0, jsx_runtime_1.jsx)("td", { className: "px-4 py-2 text-right", children: (0, jsx_runtime_1.jsxs)("div", { className: "flex items-center justify-end gap-1", children: [(0, jsx_runtime_1.jsx)("button", { onClick: () => setExpandedRow(isExpanded ? null : rowId), className: `p-1 rounded ${themeClasses.hoverBg}`, title: "View details", children: isExpanded ? ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronUp, { className: `w-4 h-4 ${themeClasses.textSecondary}` })) : ((0, jsx_runtime_1.jsx)(lucide_react_1.ChevronDown, { className: `w-4 h-4 ${themeClasses.textSecondary}` })) }), (0, jsx_runtime_1.jsx)("button", { onClick: () => handleDelete(rowId), disabled: isDeleting, className: "p-1 rounded hover:bg-red-900/20 text-red-400", title: "Delete", children: (0, jsx_runtime_1.jsx)(lucide_react_1.Trash2, { className: "w-4 h-4" }) })] }) })] }), isExpanded && ((0, jsx_runtime_1.jsx)("tr", { children: (0, jsx_runtime_1.jsx)("td", { colSpan: 7, className: `px-4 py-3 ${themeClasses.tableBg}`, children: (0, jsx_runtime_1.jsx)("pre", { className: `text-xs overflow-auto max-h-64 p-3 rounded ${isDark ? 'bg-slate-950' : 'bg-gray-100'} ${themeClasses.textSecondary}`, children: JSON.stringify(row, null, 2) }) }) }))] }, rowId));
250
- }) })] }) }))] })) })] })] }));
251
- }
252
- exports.default = DataBrowserTab;
@@ -1,73 +0,0 @@
1
- /**
2
- * =============================================================================
3
- * VIBE ADMIN LOGGING SETTINGS TAB
4
- * =============================================================================
5
- *
6
- * Admin UI for managing log levels, retention, and storage limits.
7
- * Provides environment presets, per-category levels, and manual pruning.
8
- *
9
- * =============================================================================
10
- */
11
- export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'critical';
12
- export interface LogLevels {
13
- api: LogLevel;
14
- auth: LogLevel;
15
- database: LogLevel;
16
- agent: LogLevel;
17
- system: LogLevel;
18
- }
19
- export interface RetentionSettings {
20
- debug_days: number;
21
- info_days: number;
22
- warn_days: number;
23
- error_days: number;
24
- critical_days: number;
25
- }
26
- export interface StorageLimits {
27
- max_size_mb: number;
28
- max_rows: number;
29
- }
30
- export interface UsageStats {
31
- total_rows: number;
32
- total_size_mb: number;
33
- by_level?: {
34
- debug?: {
35
- rows: number;
36
- size_mb: number;
37
- };
38
- info?: {
39
- rows: number;
40
- size_mb: number;
41
- };
42
- warn?: {
43
- rows: number;
44
- size_mb: number;
45
- };
46
- error?: {
47
- rows: number;
48
- size_mb: number;
49
- };
50
- critical?: {
51
- rows: number;
52
- size_mb: number;
53
- };
54
- };
55
- limits: StorageLimits;
56
- percent_used: number;
57
- oldest_entry?: string;
58
- }
59
- export interface LoggingSettings {
60
- levels: LogLevels;
61
- retention: RetentionSettings;
62
- limits: StorageLimits;
63
- current_usage?: UsageStats;
64
- }
65
- export interface LoggingSettingsTabProps {
66
- isDark?: boolean;
67
- /** API base path (default: /api/admin/logging) */
68
- apiBasePath?: string;
69
- /** Callback when settings are saved */
70
- onSave?: (settings: Partial<LoggingSettings>) => void;
71
- }
72
- export declare function LoggingSettingsTab({ isDark, apiBasePath, onSave, }: LoggingSettingsTabProps): import("react/jsx-runtime").JSX.Element;
73
- export default LoggingSettingsTab;