@wopr-network/platform-ui-core 1.27.8 → 1.27.9

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 (353) hide show
  1. package/next.config.ts +1 -2
  2. package/package.json +17 -17
  3. package/src/__tests__/account-switcher.test.tsx +21 -20
  4. package/src/__tests__/activity-page.test.tsx +2 -6
  5. package/src/__tests__/add-payment-method-dialog.test.tsx +9 -32
  6. package/src/__tests__/admin-api.test.ts +1 -6
  7. package/src/__tests__/admin-gpu-api.test.ts +1 -3
  8. package/src/__tests__/admin-marketplace-api.test.ts +1 -4
  9. package/src/__tests__/admin-middleware.test.ts +76 -83
  10. package/src/__tests__/affiliate-dashboard.test.tsx +3 -3
  11. package/src/__tests__/api-401-redirect.test.ts +46 -9
  12. package/src/__tests__/api-client.test.ts +3 -5
  13. package/src/__tests__/api-config.test.ts +22 -42
  14. package/src/__tests__/api-fleet-resources.test.ts +1 -2
  15. package/src/__tests__/api-fleet-trpc.test.ts +2 -8
  16. package/src/__tests__/api-null-guards.test.ts +3 -1
  17. package/src/__tests__/audit-log-table-pagination.test.tsx +2 -6
  18. package/src/__tests__/auth-password-reset.test.tsx +7 -21
  19. package/src/__tests__/auth-redirect.test.tsx +8 -2
  20. package/src/__tests__/auth.test.tsx +25 -23
  21. package/src/__tests__/auto-topup-card.test.tsx +4 -12
  22. package/src/__tests__/backups-tab.test.tsx +3 -4
  23. package/src/__tests__/billing-layout-nav-hidden.test.tsx +5 -37
  24. package/src/__tests__/billing-payment-org-invoices.test.tsx +2 -18
  25. package/src/__tests__/billing.test.tsx +8 -39
  26. package/src/__tests__/bot-settings/resources-tab.test.tsx +1 -3
  27. package/src/__tests__/bot-settings/storage-tab.test.tsx +1 -3
  28. package/src/__tests__/bot-settings/vps-upgrade-card.test.tsx +1 -3
  29. package/src/__tests__/bot-settings-restart.test.tsx +1 -3
  30. package/src/__tests__/bot-settings.test.tsx +2 -6
  31. package/src/__tests__/brand.test.ts +6 -26
  32. package/src/__tests__/buy-credits-panel.test.tsx +1 -3
  33. package/src/__tests__/buy-crypto-credits-panel.test.tsx +101 -119
  34. package/src/__tests__/capability-conflicts.test.ts +2 -8
  35. package/src/__tests__/capability-resolver.test.tsx +2 -12
  36. package/src/__tests__/channel-wizard.test.tsx +4 -17
  37. package/src/__tests__/chat/chat-panel.test.tsx +1 -4
  38. package/src/__tests__/chat-store.test.ts +5 -15
  39. package/src/__tests__/command-center.test.tsx +10 -12
  40. package/src/__tests__/compliance-retention-edit.test.tsx +3 -6
  41. package/src/__tests__/confirmation-tracker.test.tsx +3 -18
  42. package/src/__tests__/coupon-input.test.tsx +1 -3
  43. package/src/__tests__/create-instance.test.tsx +1 -3
  44. package/src/__tests__/credit-balance.test.tsx +4 -12
  45. package/src/__tests__/credits.test.tsx +32 -85
  46. package/src/__tests__/email-verification-banner.test.tsx +2 -6
  47. package/src/__tests__/error-boundaries.test.tsx +0 -1
  48. package/src/__tests__/fetch-pricing.test.ts +2 -1
  49. package/src/__tests__/field-oauth.test.tsx +2 -6
  50. package/src/__tests__/fixtures/mock-manifests-data.js +1 -3
  51. package/src/__tests__/fixtures/mock-manifests.ts +2 -4
  52. package/src/__tests__/fleet-health-timestamp.test.tsx +1 -8
  53. package/src/__tests__/fleet-health-update.test.tsx +1 -8
  54. package/src/__tests__/gpu-dashboard.test.tsx +2 -6
  55. package/src/__tests__/instance-detail.test.tsx +3 -9
  56. package/src/__tests__/instance-list.test.tsx +1 -5
  57. package/src/__tests__/layout-snapshots.test.tsx +64 -11
  58. package/src/__tests__/marketplace-admin.test.tsx +2 -6
  59. package/src/__tests__/marketplace.test.tsx +11 -35
  60. package/src/__tests__/merge-api-rates.test.ts +1 -6
  61. package/src/__tests__/middleware.test.ts +32 -219
  62. package/src/__tests__/next-config-headers.test.ts +1 -3
  63. package/src/__tests__/notifications.test.tsx +4 -11
  64. package/src/__tests__/oauth-buttons.test.tsx +36 -59
  65. package/src/__tests__/oauth-error-mapping.test.tsx +2 -6
  66. package/src/__tests__/observability.test.tsx +23 -36
  67. package/src/__tests__/onboarding-page.test.tsx +4 -6
  68. package/src/__tests__/org-billing-api.test.tsx +1 -6
  69. package/src/__tests__/plugin-install-flow.test.tsx +28 -58
  70. package/src/__tests__/plugin-registry.test.tsx +3 -11
  71. package/src/__tests__/plugin-tool-sync.test.ts +1 -3
  72. package/src/__tests__/plugins-catalog-error.test.tsx +2 -6
  73. package/src/__tests__/plugins-toggle-race.test.tsx +3 -5
  74. package/src/__tests__/portfolio-chart.test.tsx +2 -6
  75. package/src/__tests__/promotion-form.test.tsx +2 -6
  76. package/src/__tests__/promotions-list.test.tsx +1 -3
  77. package/src/__tests__/provider-key-api.test.ts +2 -1
  78. package/src/__tests__/resend-verification-button.test.tsx +8 -24
  79. package/src/__tests__/secrets-audit-pagination.test.tsx +1 -3
  80. package/src/__tests__/settings.test.tsx +11 -21
  81. package/src/__tests__/setup-checklist.test.tsx +3 -9
  82. package/src/__tests__/setup.ts +25 -6
  83. package/src/__tests__/snapshot-api.test.ts +2 -1
  84. package/src/__tests__/step-superpowers.test.tsx +1 -3
  85. package/src/__tests__/tenant-context.test.tsx +1 -6
  86. package/src/__tests__/tenant-keys-api.test.ts +3 -4
  87. package/src/__tests__/tenant-table-pagination.test.tsx +2 -6
  88. package/src/__tests__/terminal-log-cleanup.test.tsx +0 -1
  89. package/src/__tests__/transaction-history.test.tsx +190 -238
  90. package/src/__tests__/trpc-types.test.ts +2 -6
  91. package/src/__tests__/use-chat.test.ts +1 -3
  92. package/src/__tests__/use-plugin-setup-chat-stale-closure.test.ts +1 -4
  93. package/src/__tests__/use-sidecar-bridge.test.tsx +105 -0
  94. package/src/__tests__/use-webmcp.test.ts +1 -3
  95. package/src/__tests__/validate-elevenlabs-key.test.ts +2 -1
  96. package/src/__tests__/verify-page.test.tsx +4 -13
  97. package/src/__tests__/verify-redirect.test.tsx +2 -6
  98. package/src/app/(auth)/error.tsx +1 -7
  99. package/src/app/(auth)/forgot-password/page.tsx +4 -18
  100. package/src/app/(auth)/login/page.tsx +5 -22
  101. package/src/app/(auth)/reset-password/page.tsx +2 -12
  102. package/src/app/(auth)/signup/page.tsx +10 -44
  103. package/src/app/(auth)/verify/page.tsx +47 -0
  104. package/src/app/(dashboard)/billing/credits/page.tsx +14 -67
  105. package/src/app/(dashboard)/billing/error.tsx +2 -10
  106. package/src/app/(dashboard)/billing/layout.tsx +12 -62
  107. package/src/app/(dashboard)/billing/payment/page.tsx +17 -68
  108. package/src/app/(dashboard)/billing/plans/page.tsx +3 -9
  109. package/src/app/(dashboard)/billing/usage/hosted/page.tsx +8 -25
  110. package/src/app/(dashboard)/billing/usage/page.tsx +63 -103
  111. package/src/app/(dashboard)/changesets/[id]/changeset-detail-client.tsx +9 -27
  112. package/src/app/(dashboard)/changesets/[id]/error.tsx +2 -6
  113. package/src/app/(dashboard)/changesets/error.tsx +1 -7
  114. package/src/app/(dashboard)/chat/page.tsx +2 -6
  115. package/src/app/(dashboard)/dashboard/network/page.tsx +5 -19
  116. package/src/app/(dashboard)/error.tsx +1 -7
  117. package/src/app/(dashboard)/layout.tsx +15 -36
  118. package/src/app/(dashboard)/marketplace/[plugin]/page.tsx +14 -51
  119. package/src/app/(dashboard)/marketplace/error.tsx +1 -7
  120. package/src/app/(dashboard)/marketplace/page.tsx +6 -27
  121. package/src/app/(dashboard)/not-found.tsx +2 -5
  122. package/src/app/(dashboard)/onboarding/page.tsx +5 -22
  123. package/src/app/(dashboard)/settings/account/page.tsx +1 -6
  124. package/src/app/(dashboard)/settings/activity/page.tsx +8 -34
  125. package/src/app/(dashboard)/settings/api-keys/page.tsx +15 -60
  126. package/src/app/(dashboard)/settings/brain/page.tsx +9 -31
  127. package/src/app/(dashboard)/settings/error.tsx +2 -10
  128. package/src/app/(dashboard)/settings/notifications/page.tsx +2 -6
  129. package/src/app/(dashboard)/settings/org/page.tsx +13 -56
  130. package/src/app/(dashboard)/settings/page.tsx +1 -0
  131. package/src/app/(dashboard)/settings/profile/page.tsx +126 -73
  132. package/src/app/(dashboard)/settings/providers/page.tsx +21 -78
  133. package/src/app/(dashboard)/settings/secrets/page.tsx +13 -58
  134. package/src/app/(dashboard)/settings/security/page.tsx +31 -111
  135. package/src/app/admin/email-templates/email-templates-client.tsx +15 -58
  136. package/src/app/admin/error.tsx +1 -7
  137. package/src/app/admin/fleet-updates/error.tsx +1 -7
  138. package/src/app/admin/fleet-updates/fleet-updates-client.tsx +10 -50
  139. package/src/app/admin/layout.tsx +4 -0
  140. package/src/app/admin/payment-methods/page.tsx +9 -38
  141. package/src/app/admin/products/error.tsx +2 -7
  142. package/src/app/admin/products/page.tsx +1 -4
  143. package/src/app/admin/promotions/[id]/page.tsx +9 -38
  144. package/src/app/admin/promotions/page.tsx +9 -36
  145. package/src/app/admin/rate-overrides/page.tsx +9 -45
  146. package/src/app/auth/callback/[provider]/page.tsx +1 -8
  147. package/src/app/auth/verify/page.tsx +9 -36
  148. package/src/app/channels/error.tsx +2 -10
  149. package/src/app/channels/layout.tsx +9 -0
  150. package/src/app/channels/page.tsx +8 -20
  151. package/src/app/channels/setup/[plugin]/page.tsx +3 -5
  152. package/src/app/error.tsx +1 -7
  153. package/src/app/fleet/error.tsx +1 -7
  154. package/src/app/fleet/layout.tsx +5 -0
  155. package/src/app/fleet/settings/page.tsx +1 -3
  156. package/src/app/global-error.tsx +2 -10
  157. package/src/app/globals.css +1 -4
  158. package/src/app/instances/[id]/instance-detail-client.tsx +51 -125
  159. package/src/app/instances/error.tsx +2 -10
  160. package/src/app/instances/instance-list-client.tsx +20 -69
  161. package/src/app/instances/layout.tsx +9 -0
  162. package/src/app/instances/new/create-instance-client.tsx +10 -31
  163. package/src/app/layout.tsx +2 -10
  164. package/src/app/not-found.tsx +1 -3
  165. package/src/app/page.tsx +1 -2
  166. package/src/app/plugins/error.tsx +2 -10
  167. package/src/app/plugins/layout.tsx +5 -0
  168. package/src/app/plugins/page.tsx +16 -48
  169. package/src/app/pricing/error.tsx +1 -7
  170. package/src/app/privacy/page.tsx +93 -150
  171. package/src/app/status/error.tsx +1 -7
  172. package/src/app/terms/page.tsx +89 -144
  173. package/src/components/account-switcher.tsx +25 -52
  174. package/src/components/admin/accounting-dashboard.tsx +1 -3
  175. package/src/components/admin/admin-guard.tsx +1 -3
  176. package/src/components/admin/admin-nav.tsx +1 -3
  177. package/src/components/admin/affiliate-dashboard.tsx +25 -94
  178. package/src/components/admin/audit-log-table.tsx +13 -49
  179. package/src/components/admin/billing-health-dashboard.tsx +7 -25
  180. package/src/components/admin/bulk-actions-bar.test.tsx +1 -7
  181. package/src/components/admin/bulk-actions-bar.tsx +1 -3
  182. package/src/components/admin/bulk-export-dialog.test.tsx +1 -7
  183. package/src/components/admin/bulk-export-dialog.tsx +6 -32
  184. package/src/components/admin/bulk-grant-dialog.test.tsx +2 -6
  185. package/src/components/admin/bulk-grant-dialog.tsx +4 -15
  186. package/src/components/admin/bulk-preview-dialog.tsx +3 -12
  187. package/src/components/admin/bulk-reactivate-dialog.tsx +1 -7
  188. package/src/components/admin/bulk-select-all-banner.tsx +1 -6
  189. package/src/components/admin/bulk-suspend-dialog.tsx +5 -12
  190. package/src/components/admin/bulk-undo-toast.tsx +1 -2
  191. package/src/components/admin/compliance-dashboard.tsx +31 -101
  192. package/src/components/admin/gpu-dashboard.tsx +21 -70
  193. package/src/components/admin/grant-credits-dialog.tsx +4 -17
  194. package/src/components/admin/incident-dashboard.tsx +10 -25
  195. package/src/components/admin/inference-dashboard.tsx +14 -54
  196. package/src/components/admin/marketplace-admin.tsx +18 -60
  197. package/src/components/admin/migrations-dashboard.tsx +9 -42
  198. package/src/components/admin/onboarding-dashboard.tsx +14 -64
  199. package/src/components/admin/pool-config-dashboard.tsx +4 -10
  200. package/src/components/admin/products/fleet-form.tsx +2 -11
  201. package/src/components/admin/products/nav-editor.tsx +3 -10
  202. package/src/components/admin/promotions/promotion-form.tsx +9 -42
  203. package/src/components/admin/roles-dashboard.tsx +7 -34
  204. package/src/components/admin/suspend-dialog.tsx +4 -11
  205. package/src/components/admin/tenant-notes-panel.tsx +1 -3
  206. package/src/components/admin/tenant-row-actions.tsx +4 -20
  207. package/src/components/admin/tenant-table.tsx +12 -49
  208. package/src/components/auth/auth-redirect.tsx +11 -3
  209. package/src/components/auth/email-verification-result-banner.tsx +1 -3
  210. package/src/components/auth/resend-verification-button.tsx +2 -10
  211. package/src/components/auth/wopr-wordmark.tsx +1 -3
  212. package/src/components/billing/add-payment-method-dialog.tsx +1 -2
  213. package/src/components/billing/affiliate-dashboard.tsx +4 -16
  214. package/src/components/billing/amount-selector.tsx +1 -3
  215. package/src/components/billing/auto-topup-card.tsx +2 -11
  216. package/src/components/billing/buy-credits-panel.tsx +4 -14
  217. package/src/components/billing/byok-callout.tsx +6 -8
  218. package/src/components/billing/confirmation-tracker.tsx +4 -14
  219. package/src/components/billing/credit-balance-badge.tsx +22 -0
  220. package/src/components/billing/credit-balance.tsx +3 -9
  221. package/src/components/billing/crypto-checkout.tsx +5 -24
  222. package/src/components/billing/degraded-state-banner.tsx +1 -3
  223. package/src/components/billing/deposit-view.tsx +301 -41
  224. package/src/components/billing/dividend-banner.tsx +1 -3
  225. package/src/components/billing/dividend-eligibility.tsx +3 -12
  226. package/src/components/billing/dividend-pool-stats.tsx +6 -20
  227. package/src/components/billing/first-dividend-dialog.tsx +2 -2
  228. package/src/components/billing/org-billing-page.tsx +8 -31
  229. package/src/components/billing/payment-method-picker.tsx +2 -10
  230. package/src/components/billing/suspension-banner.tsx +2 -7
  231. package/src/components/billing/transaction-history.tsx +10 -58
  232. package/src/components/billing/unified-checkout.tsx +547 -0
  233. package/src/components/bot-settings/backups-tab.tsx +9 -33
  234. package/src/components/bot-settings/bot-settings-client.tsx +32 -134
  235. package/src/components/bot-settings/resources-tab.tsx +2 -9
  236. package/src/components/bot-settings/storage-tab.tsx +19 -48
  237. package/src/components/bot-settings/vps-info-panel.tsx +3 -11
  238. package/src/components/bot-settings/vps-upgrade-card.tsx +3 -4
  239. package/src/components/brand-hydrator.tsx +13 -0
  240. package/src/components/channel-wizard/field-interactive.tsx +1 -3
  241. package/src/components/channel-wizard/field-qr.tsx +10 -39
  242. package/src/components/channel-wizard/step-renderer.tsx +5 -28
  243. package/src/components/channel-wizard/wizard.tsx +6 -31
  244. package/src/components/chat/chat-message.tsx +1 -4
  245. package/src/components/chat/chat-panel.tsx +4 -18
  246. package/src/components/chat/chat-widget.tsx +3 -14
  247. package/src/components/dashboard/command-center.tsx +15 -61
  248. package/src/components/fleet/update-settings-card.tsx +7 -23
  249. package/src/components/instance-update-banner.tsx +130 -0
  250. package/src/components/instances/friends-tab.test.tsx +2 -9
  251. package/src/components/instances/friends-tab.tsx +18 -74
  252. package/src/components/instances/update-available-badge.tsx +2 -11
  253. package/src/components/landing/hero.tsx +3 -9
  254. package/src/components/landing/landing-page.tsx +1 -3
  255. package/src/components/landing/portfolio-chart.tsx +4 -9
  256. package/src/components/landing/story-sections.tsx +1 -3
  257. package/src/components/landing/terminal-sequence.tsx +4 -17
  258. package/src/components/marketplace/empty-state.tsx +2 -6
  259. package/src/components/marketplace/first-visit-hero.tsx +1 -3
  260. package/src/components/marketplace/install-wizard.tsx +20 -77
  261. package/src/components/marketplace/marketplace-tabs.tsx +1 -4
  262. package/src/components/marketplace/plugin-card.tsx +2 -9
  263. package/src/components/marketplace/superpower-content.tsx +1 -3
  264. package/src/components/marketplace/terminal-search.tsx +2 -8
  265. package/src/components/oauth-buttons.tsx +29 -14
  266. package/src/components/observability/fleet-health.tsx +5 -18
  267. package/src/components/observability/health-overview.tsx +7 -20
  268. package/src/components/observability/logs-viewer.tsx +8 -32
  269. package/src/components/observability/metrics-dashboard.tsx +2 -15
  270. package/src/components/onboarding/fallback-setup.tsx +6 -25
  271. package/src/components/onboarding/setup-checklist.tsx +18 -51
  272. package/src/components/onboarding/step-superpowers.tsx +1 -4
  273. package/src/components/plugin-setup/setup-chat-panel.tsx +6 -22
  274. package/src/components/pricing/dividend-calculator.tsx +6 -12
  275. package/src/components/pricing/dividend-stats.tsx +5 -17
  276. package/src/components/pricing/pricing-page.tsx +17 -36
  277. package/src/components/settings/create-org-wizard.tsx +2 -5
  278. package/src/components/sidebar.tsx +7 -42
  279. package/src/components/sidecar-frame.tsx +78 -0
  280. package/src/components/status/status-page.tsx +6 -28
  281. package/src/components/ui/alert-dialog.tsx +8 -25
  282. package/src/components/ui/badge.tsx +2 -8
  283. package/src/components/ui/banner.tsx +1 -6
  284. package/src/components/ui/card.tsx +5 -24
  285. package/src/components/ui/checkbox.tsx +1 -5
  286. package/src/components/ui/collapsible.tsx +3 -8
  287. package/src/components/ui/dialog.tsx +4 -10
  288. package/src/components/ui/dropdown-menu.tsx +9 -18
  289. package/src/components/ui/form.tsx +2 -16
  290. package/src/components/ui/popover.tsx +3 -23
  291. package/src/components/ui/progress.tsx +1 -5
  292. package/src/components/ui/radio-group.tsx +3 -15
  293. package/src/components/ui/select.tsx +4 -17
  294. package/src/components/ui/sheet.tsx +5 -19
  295. package/src/components/ui/skeleton.tsx +1 -7
  296. package/src/components/ui/table.tsx +5 -22
  297. package/src/components/ui/tabs.tsx +3 -13
  298. package/src/components/ui/tooltip.tsx +1 -1
  299. package/src/components/unified-sidebar.tsx +493 -0
  300. package/src/hooks/__tests__/use-fleet-sse.test.ts +1 -4
  301. package/src/hooks/__tests__/use-save-queue.test.ts +2 -8
  302. package/src/hooks/use-credit-balance.ts +27 -0
  303. package/src/hooks/use-my-org-role.ts +1 -3
  304. package/src/hooks/use-plugin-registry.ts +8 -14
  305. package/src/hooks/use-plugin-setup-chat.ts +2 -5
  306. package/src/hooks/use-sidecar-bridge.tsx +148 -0
  307. package/src/hooks/use-webmcp.ts +1 -4
  308. package/src/lib/__tests__/admin-api.test.ts +1 -3
  309. package/src/lib/__tests__/api-bot-crud.test.ts +8 -18
  310. package/src/lib/__tests__/api-fetch.test.ts +4 -16
  311. package/src/lib/__tests__/org-billing-api.test.ts +1 -3
  312. package/src/lib/__tests__/pricing-data.test.ts +0 -8
  313. package/src/lib/__tests__/settings-api.test.ts +1 -3
  314. package/src/lib/admin-affiliate-api.ts +2 -7
  315. package/src/lib/admin-api.ts +6 -26
  316. package/src/lib/admin-incident-api.ts +11 -19
  317. package/src/lib/admin-marketplace-api.ts +1 -5
  318. package/src/lib/api-config.test.ts +5 -50
  319. package/src/lib/api.ts +143 -122
  320. package/src/lib/auth-client.ts +1 -2
  321. package/src/lib/bot-settings-data.ts +11 -36
  322. package/src/lib/brand-config.ts +56 -115
  323. package/src/lib/brand.ts +2 -15
  324. package/src/lib/chat/use-chat.ts +2 -7
  325. package/src/lib/cost-comparison-data.test.ts +1 -3
  326. package/src/lib/cost-comparison-data.ts +1 -4
  327. package/src/lib/errors.ts +1 -4
  328. package/src/lib/fetch-utils.test.ts +26 -9
  329. package/src/lib/fetch-utils.ts +40 -11
  330. package/src/lib/logger.ts +2 -0
  331. package/src/lib/marketplace-data.ts +3 -11
  332. package/src/lib/oauth-errors.ts +2 -4
  333. package/src/lib/onboarding-data.ts +3 -11
  334. package/src/lib/org-api.ts +2 -10
  335. package/src/lib/org-billing-api.ts +5 -19
  336. package/src/lib/plugin/tool-definitions.ts +1 -2
  337. package/src/lib/require-auth.ts +57 -0
  338. package/src/lib/settings-api.ts +1 -4
  339. package/src/lib/sidecar-routes.ts +43 -0
  340. package/src/lib/trpc-server.ts +49 -0
  341. package/src/lib/trpc-types.ts +4 -6
  342. package/src/lib/trpc.tsx +12 -4
  343. package/src/lib/validate-redirect-url.ts +1 -4
  344. package/src/lib/webmcp/marketplace-onboarding-tools.ts +6 -16
  345. package/src/lib/webmcp/register.ts +1 -4
  346. package/src/lib/webmcp/tools.ts +2 -9
  347. package/src/proxy.ts +35 -212
  348. package/src/types/missing-deps.d.ts +2 -8
  349. package/tsconfig.json +1 -8
  350. package/biome.json +0 -52
  351. package/src/__tests__/__snapshots__/layout-snapshots.test.tsx.snap +0 -741
  352. package/src/__tests__/billing-byok-callout.test.tsx +0 -76
  353. package/src/lib/__tests__/__snapshots__/pricing-data.test.ts.snap +0 -112
@@ -26,9 +26,7 @@ export default function ChatPage() {
26
26
  className={`h-2 w-2 rounded-full inline-block ${isConnected ? "bg-terminal" : "bg-destructive"}`}
27
27
  aria-label={isConnected ? "Connected" : "Disconnected"}
28
28
  />
29
- <h1 className="text-sm font-mono uppercase tracking-wider text-muted-foreground">
30
- {brandName()}
31
- </h1>
29
+ <h1 className="text-sm font-mono uppercase tracking-wider text-muted-foreground">{brandName()}</h1>
32
30
  </div>
33
31
  <Button
34
32
  type="button"
@@ -50,9 +48,7 @@ export default function ChatPage() {
50
48
  </p>
51
49
  )}
52
50
  {messages.length === 0 && !isConnected && (
53
- <p className="text-center text-xs text-muted-foreground animate-ellipsis">
54
- Connecting to {brandName()}
55
- </p>
51
+ <p className="text-center text-xs text-muted-foreground animate-ellipsis">Connecting to {brandName()}</p>
56
52
  )}
57
53
  {messages.map((msg) => (
58
54
  <ChatMessage key={msg.id} message={msg} />
@@ -2,13 +2,7 @@
2
2
 
3
3
  import { useEffect, useState } from "react";
4
4
  import { FriendsTab } from "@/components/instances/friends-tab";
5
- import {
6
- Select,
7
- SelectContent,
8
- SelectItem,
9
- SelectTrigger,
10
- SelectValue,
11
- } from "@/components/ui/select";
5
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
12
6
  import { Skeleton } from "@/components/ui/skeleton";
13
7
  import type { Instance } from "@/lib/api";
14
8
  import { listInstances } from "@/lib/api";
@@ -50,8 +44,7 @@ export default function NetworkPage() {
50
44
  <div>
51
45
  <h1 className="text-2xl font-bold tracking-widest uppercase">Friends &amp; Network</h1>
52
46
  <p className="mt-1 text-sm text-muted-foreground">
53
- Manage P2P connections, friend requests, and auto-accept rules for your {productName()}{" "}
54
- bot instances.
47
+ Manage P2P connections, friend requests, and auto-accept rules for your {productName()} bot instances.
55
48
  </p>
56
49
  </div>
57
50
  <div className="w-full sm:w-56 shrink-0">
@@ -62,10 +55,7 @@ export default function NetworkPage() {
62
55
  ) : instances.length === 0 ? (
63
56
  <p className="text-sm text-muted-foreground">No instances found.</p>
64
57
  ) : (
65
- <Select
66
- value={selectedInstanceId ?? ""}
67
- onValueChange={(v) => setSelectedInstanceId(v)}
68
- >
58
+ <Select value={selectedInstanceId ?? ""} onValueChange={(v) => setSelectedInstanceId(v)}>
69
59
  <SelectTrigger className="w-full" aria-label="Select instance">
70
60
  <SelectValue placeholder="Select instance..." />
71
61
  </SelectTrigger>
@@ -83,15 +73,11 @@ export default function NetworkPage() {
83
73
 
84
74
  {!loading && !error && !selectedInstanceId && instances.length > 0 && (
85
75
  <div className="flex h-64 flex-col items-center justify-center gap-3 rounded-sm border border-dashed border-terminal/20">
86
- <p className="font-mono text-sm text-terminal/60">
87
- &gt; SELECT AN INSTANCE TO MANAGE FRIENDS
88
- </p>
76
+ <p className="font-mono text-sm text-terminal/60">&gt; SELECT AN INSTANCE TO MANAGE FRIENDS</p>
89
77
  </div>
90
78
  )}
91
79
 
92
- {selectedInstanceId && (
93
- <FriendsTab key={selectedInstanceId} instanceId={selectedInstanceId} />
94
- )}
80
+ {selectedInstanceId && <FriendsTab key={selectedInstanceId} instanceId={selectedInstanceId} />}
95
81
  </div>
96
82
  );
97
83
  }
@@ -8,13 +8,7 @@ import { logger } from "@/lib/logger";
8
8
 
9
9
  const log = logger("error-boundary:dashboard");
10
10
 
11
- export default function DashboardError({
12
- error,
13
- reset,
14
- }: {
15
- error: Error & { digest?: string };
16
- reset: () => void;
17
- }) {
11
+ export default function DashboardError({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
18
12
  const [showDetails, setShowDetails] = useState(false);
19
13
  const isDev = process.env.NODE_ENV === "development";
20
14
 
@@ -11,10 +11,9 @@
11
11
  */
12
12
  "use client";
13
13
 
14
- import { AnimatePresence, motion } from "framer-motion";
15
14
  import { MenuIcon } from "lucide-react";
16
15
  import { usePathname } from "next/navigation";
17
- import { Suspense, useEffect, useState } from "react";
16
+ import { Fragment, Suspense, useEffect, useState } from "react";
18
17
  import { EmailVerificationBanner } from "@/components/auth/email-verification-banner";
19
18
  import { EmailVerificationResultBanner } from "@/components/auth/email-verification-result-banner";
20
19
  import { SuspensionBanner } from "@/components/billing/suspension-banner";
@@ -26,15 +25,16 @@ import { usePageContext } from "@/hooks/use-page-context";
26
25
  import { useWebMCP } from "@/hooks/use-webmcp";
27
26
  import { getBrandConfig, productName } from "@/lib/brand-config";
28
27
  import { ChatProvider } from "@/lib/chat/chat-context";
28
+ import { useRequireAuth } from "@/lib/require-auth";
29
29
 
30
30
  export default function DashboardLayout({
31
31
  children,
32
32
  }: Readonly<{
33
33
  children: React.ReactNode;
34
34
  }>) {
35
+ const { isPending, isAuthed } = useRequireAuth();
35
36
  useWebMCP();
36
37
  usePageContext();
37
-
38
38
  const pathname = usePathname();
39
39
  const [sheetOpen, setSheetOpen] = useState(false);
40
40
 
@@ -44,8 +44,13 @@ export default function DashboardLayout({
44
44
  setSheetOpen(false);
45
45
  }, [pathname]);
46
46
 
47
+ if (isPending || !isAuthed) return null;
48
+
49
+ const chatEnabled = getBrandConfig().chatEnabled;
50
+ const Wrapper = chatEnabled ? ChatProvider : Fragment;
51
+
47
52
  return (
48
- <ChatProvider>
53
+ <Wrapper>
49
54
  {/* Desktop layout - hidden on mobile with CSS */}
50
55
  <div className="hidden lg:flex h-screen">
51
56
  <Sidebar />
@@ -55,23 +60,12 @@ export default function DashboardLayout({
55
60
  <Suspense>
56
61
  <EmailVerificationResultBanner />
57
62
  </Suspense>
58
- <AnimatePresence mode="wait">
59
- <motion.main
60
- key={pathname}
61
- initial={{ opacity: 0 }}
62
- animate={{ opacity: 1 }}
63
- exit={{ opacity: 0 }}
64
- transition={{ duration: 0.2, ease: "easeInOut" }}
65
- className="flex-1 overflow-auto"
66
- >
67
- {children}
68
- </motion.main>
69
- </AnimatePresence>
63
+ <main className="flex-1">{children}</main>
70
64
  </div>
71
65
  </div>
72
66
 
73
67
  {/* Mobile layout - hidden on desktop with CSS */}
74
- <div className="crt-scanlines flex lg:hidden h-screen flex-col">
68
+ <div className="crt-scanlines flex lg:hidden h-screen flex-col overflow-auto">
75
69
  <header className="flex h-14 shrink-0 items-center border-b border-sidebar-border bg-sidebar px-4 gap-3">
76
70
  <Sheet open={sheetOpen} onOpenChange={setSheetOpen}>
77
71
  <SheetTrigger asChild>
@@ -79,11 +73,7 @@ export default function DashboardLayout({
79
73
  <MenuIcon className="size-5" />
80
74
  </Button>
81
75
  </SheetTrigger>
82
- <SheetContent
83
- side="left"
84
- className="w-64 bg-sidebar text-sidebar-foreground p-0"
85
- aria-label="Navigation"
86
- >
76
+ <SheetContent side="left" className="w-64 bg-sidebar text-sidebar-foreground p-0" aria-label="Navigation">
87
77
  <SidebarContent onNavigate={() => setSheetOpen(false)} />
88
78
  </SheetContent>
89
79
  </Sheet>
@@ -94,20 +84,9 @@ export default function DashboardLayout({
94
84
  <Suspense>
95
85
  <EmailVerificationResultBanner />
96
86
  </Suspense>
97
- <AnimatePresence mode="wait">
98
- <motion.main
99
- key={pathname}
100
- initial={{ opacity: 0 }}
101
- animate={{ opacity: 1 }}
102
- exit={{ opacity: 0 }}
103
- transition={{ duration: 0.2, ease: "easeInOut" }}
104
- className="flex-1 overflow-auto"
105
- >
106
- {children}
107
- </motion.main>
108
- </AnimatePresence>
87
+ <main className="flex-1">{children}</main>
109
88
  </div>
110
- {getBrandConfig().chatEnabled && !pathname.startsWith("/chat") && <ChatWidget />}
111
- </ChatProvider>
89
+ {chatEnabled && !pathname.startsWith("/chat") && <ChatWidget />}
90
+ </Wrapper>
112
91
  );
113
92
  }
@@ -83,6 +83,7 @@ export function TerminalLog({ plugin, onDone }: { plugin: PluginManifest; onDone
83
83
  <div ref={containerRef} className="max-h-48 overflow-y-auto space-y-1">
84
84
  {lines.map((line, idx) => (
85
85
  <motion.div
86
+ // biome-ignore lint/suspicious/noArrayIndexKey: static list, index key is safe
86
87
  key={`line-${idx}-${line.slice(0, 10)}`}
87
88
  initial={{ opacity: 0, x: -5 }}
88
89
  animate={{ opacity: 1, x: 0 }}
@@ -156,16 +157,9 @@ export default function PluginDetailPage() {
156
157
  setInstallError(null);
157
158
  try {
158
159
  const providerChoices = (config._providerChoices as Record<string, string>) ?? {};
159
- const primaryProviderOverrides =
160
- (config._primaryProviderOverrides as Record<string, string>) ?? undefined;
160
+ const primaryProviderOverrides = (config._primaryProviderOverrides as Record<string, string>) ?? undefined;
161
161
  const { _providerChoices: _, _primaryProviderOverrides: __, ...pluginConfig } = config;
162
- const result = await installPlugin(
163
- plugin.id,
164
- botId,
165
- pluginConfig,
166
- providerChoices,
167
- primaryProviderOverrides,
168
- );
162
+ const result = await installPlugin(plugin.id, botId, pluginConfig, providerChoices, primaryProviderOverrides);
169
163
  if (!result.dispatched) {
170
164
  if (result.dispatchError === "bot_not_deployed") {
171
165
  toast.warning("Bot isn't running — plugin will activate on next start");
@@ -230,11 +224,7 @@ export default function PluginDetailPage() {
230
224
  if (installing) {
231
225
  return (
232
226
  <div className="mx-auto max-w-xl p-6">
233
- <InstallWizard
234
- plugin={plugin}
235
- onComplete={handleInstallComplete}
236
- onCancel={() => setInstalling(false)}
237
- />
227
+ <InstallWizard plugin={plugin} onComplete={handleInstallComplete} onCancel={() => setInstalling(false)} />
238
228
  </div>
239
229
  );
240
230
  }
@@ -319,12 +309,7 @@ export default function PluginDetailPage() {
319
309
 
320
310
  {/* Outcome bullets */}
321
311
  {plugin.superpowerOutcomes && plugin.superpowerOutcomes.length > 0 && (
322
- <motion.div
323
- initial={{ opacity: 0 }}
324
- animate={{ opacity: 1 }}
325
- transition={{ delay: 0.2 }}
326
- className="space-y-2"
327
- >
312
+ <motion.div initial={{ opacity: 0 }} animate={{ opacity: 1 }} transition={{ delay: 0.2 }} className="space-y-2">
328
313
  <h2 className="text-base font-bold">What she can do</h2>
329
314
  <ul className="space-y-2">
330
315
  {plugin.superpowerOutcomes.map((outcome) => (
@@ -347,19 +332,13 @@ export default function PluginDetailPage() {
347
332
  {plugin.capabilities.map((cap) => {
348
333
  const color = getCapabilityColor(cap);
349
334
  return (
350
- <Badge
351
- key={cap}
352
- variant="outline"
353
- className={`${color.bg} ${color.text} ${color.border}`}
354
- >
335
+ <Badge key={cap} variant="outline" className={`${color.bg} ${color.text} ${color.border}`}>
355
336
  {cap}
356
337
  </Badge>
357
338
  );
358
339
  })}
359
340
  {hostedAvailable && (
360
- <Badge className="bg-emerald-500/15 text-emerald-500 border-emerald-500/25">
361
- {brandName()} Hosted
362
- </Badge>
341
+ <Badge className="bg-emerald-500/15 text-emerald-500 border-emerald-500/25">{brandName()} Hosted</Badge>
363
342
  )}
364
343
  </motion.div>
365
344
 
@@ -408,17 +387,12 @@ export default function PluginDetailPage() {
408
387
  <Card>
409
388
  <CardHeader>
410
389
  <CardTitle className="text-base">{brandName()} Hosted Options</CardTitle>
411
- <CardDescription>
412
- Capabilities available as managed services -- no keys needed.
413
- </CardDescription>
390
+ <CardDescription>Capabilities available as managed services -- no keys needed.</CardDescription>
414
391
  </CardHeader>
415
392
  <CardContent>
416
393
  <ul className="space-y-3">
417
394
  {hostedAdapters.map((adapter) => (
418
- <li
419
- key={adapter.capability}
420
- className="flex items-center justify-between rounded-lg border p-3"
421
- >
395
+ <li key={adapter.capability} className="flex items-center justify-between rounded-lg border p-3">
422
396
  <div>
423
397
  <p className="text-sm font-medium">{adapter.label}</p>
424
398
  <p className="text-xs text-muted-foreground">{adapter.description}</p>
@@ -470,15 +444,12 @@ export default function PluginDetailPage() {
470
444
  <CardHeader>
471
445
  <CardTitle className="text-base">Configuration Schema</CardTitle>
472
446
  <CardDescription>
473
- Fields auto-generated from the plugin manifest. These will be filled during
474
- installation.
447
+ Fields auto-generated from the plugin manifest. These will be filled during installation.
475
448
  </CardDescription>
476
449
  </CardHeader>
477
450
  <CardContent>
478
451
  {plugin.configSchema.length === 0 ? (
479
- <p className="text-sm text-muted-foreground">
480
- This plugin has no configuration fields.
481
- </p>
452
+ <p className="text-sm text-muted-foreground">This plugin has no configuration fields.</p>
482
453
  ) : (
483
454
  <div className="space-y-3">
484
455
  {plugin.configSchema.map((field) => (
@@ -489,25 +460,17 @@ export default function PluginDetailPage() {
489
460
  {field.type}
490
461
  </Badge>
491
462
  {field.required && (
492
- <Badge
493
- variant="outline"
494
- className="text-[10px] border-red-500/25 text-red-500"
495
- >
463
+ <Badge variant="outline" className="text-[10px] border-red-500/25 text-red-500">
496
464
  required
497
465
  </Badge>
498
466
  )}
499
467
  {field.secret && (
500
- <Badge
501
- variant="outline"
502
- className="text-[10px] border-yellow-500/25 text-yellow-500"
503
- >
468
+ <Badge variant="outline" className="text-[10px] border-yellow-500/25 text-yellow-500">
504
469
  secret
505
470
  </Badge>
506
471
  )}
507
472
  </div>
508
- {field.description && (
509
- <p className="mt-1 text-xs text-muted-foreground">{field.description}</p>
510
- )}
473
+ {field.description && <p className="mt-1 text-xs text-muted-foreground">{field.description}</p>}
511
474
  </div>
512
475
  ))}
513
476
  </div>
@@ -8,13 +8,7 @@ import { logger } from "@/lib/logger";
8
8
 
9
9
  const log = logger("error-boundary:marketplace");
10
10
 
11
- export default function MarketplaceError({
12
- error,
13
- reset,
14
- }: {
15
- error: Error & { digest?: string };
16
- reset: () => void;
17
- }) {
11
+ export default function MarketplaceError({ error, reset }: { error: Error & { digest?: string }; reset: () => void }) {
18
12
  const [showDetails, setShowDetails] = useState(false);
19
13
  const isDev = process.env.NODE_ENV === "development";
20
14
 
@@ -104,10 +104,7 @@ export default function MarketplacePage() {
104
104
  }
105
105
 
106
106
  // Superpower plugins
107
- const superpowers = useMemo(
108
- () => plugins.filter((p) => p.marketplaceTab === "superpower"),
109
- [plugins],
110
- );
107
+ const superpowers = useMemo(() => plugins.filter((p) => p.marketplaceTab === "superpower"), [plugins]);
111
108
 
112
109
  // Category counts for current tab
113
110
  const categoryCounts = useMemo(() => {
@@ -199,18 +196,14 @@ export default function MarketplacePage() {
199
196
  <>
200
197
  {/* First-visit cinematic overlay */}
201
198
  <AnimatePresence>
202
- {showFirstVisit && (
203
- <FirstVisitHero superpowers={superpowers} onDismiss={handleDismissFirstVisit} />
204
- )}
199
+ {showFirstVisit && <FirstVisitHero superpowers={superpowers} onDismiss={handleDismissFirstVisit} />}
205
200
  </AnimatePresence>
206
201
 
207
202
  <div className="p-6 space-y-6">
208
203
  {/* Page header */}
209
204
  <div>
210
205
  <h1 className="text-2xl font-bold tracking-tight">Browse Superpowers</h1>
211
- <p className="text-sm text-muted-foreground">
212
- Give your {productName()} abilities it was born to have.
213
- </p>
206
+ <p className="text-sm text-muted-foreground">Give your {productName()} abilities it was born to have.</p>
214
207
  </div>
215
208
 
216
209
  {/* Featured hero section — hidden during search */}
@@ -231,11 +224,7 @@ export default function MarketplacePage() {
231
224
  />
232
225
 
233
226
  {activeTab !== "superpower" && (
234
- <CategoryFilter
235
- selected={selectedCategory}
236
- onSelect={setSelectedCategory}
237
- counts={categoryCounts}
238
- />
227
+ <CategoryFilter selected={selectedCategory} onSelect={setSelectedCategory} counts={categoryCounts} />
239
228
  )}
240
229
 
241
230
  {/* Plugin grid */}
@@ -245,19 +234,9 @@ export default function MarketplacePage() {
245
234
  <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
246
235
  {filtered.map((plugin, i) =>
247
236
  activeTab === "superpower" ? (
248
- <SuperpowerCard
249
- key={plugin.id}
250
- plugin={plugin}
251
- index={i}
252
- installed={installedIds.has(plugin.id)}
253
- />
237
+ <SuperpowerCard key={plugin.id} plugin={plugin} index={i} installed={installedIds.has(plugin.id)} />
254
238
  ) : (
255
- <PluginCard
256
- key={plugin.id}
257
- plugin={plugin}
258
- index={i}
259
- installed={installedIds.has(plugin.id)}
260
- />
239
+ <PluginCard key={plugin.id} plugin={plugin} index={i} installed={installedIds.has(plugin.id)} />
261
240
  ),
262
241
  )}
263
242
  </div>
@@ -10,9 +10,7 @@ export default function DashboardNotFound() {
10
10
  <CardHeader>
11
11
  <div className="flex items-center gap-3">
12
12
  <TerminalIcon className="size-5 text-terminal" />
13
- <span className="text-sm font-medium uppercase tracking-widest text-muted-foreground">
14
- system error
15
- </span>
13
+ <span className="text-sm font-medium uppercase tracking-widest text-muted-foreground">system error</span>
16
14
  </div>
17
15
  </CardHeader>
18
16
  <CardContent className="space-y-4">
@@ -22,8 +20,7 @@ export default function DashboardNotFound() {
22
20
  <span className="animate-ellipsis" />
23
21
  </p>
24
22
  <p className="text-sm text-muted-foreground">
25
- The requested page does not exist or has been moved. Check the URL or navigate back to
26
- the dashboard.
23
+ The requested page does not exist or has been moved. Check the URL or navigate back to the dashboard.
27
24
  </p>
28
25
  </CardContent>
29
26
  <CardFooter className="gap-3">
@@ -5,14 +5,7 @@ import { Bot, ChevronRight, Rocket, Sparkles } from "lucide-react";
5
5
  import { useRouter } from "next/navigation";
6
6
  import { useEffect, useState } from "react";
7
7
  import { Button } from "@/components/ui/button";
8
- import {
9
- Card,
10
- CardContent,
11
- CardDescription,
12
- CardFooter,
13
- CardHeader,
14
- CardTitle,
15
- } from "@/components/ui/card";
8
+ import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
16
9
  import { Input } from "@/components/ui/input";
17
10
  import { getBrandConfig, storageKey } from "@/lib/brand-config";
18
11
  import { presets } from "@/lib/onboarding-data";
@@ -103,9 +96,7 @@ export default function OnboardingPage() {
103
96
  {[0, 1, 2].map((s) => (
104
97
  <div
105
98
  key={s}
106
- className={`h-1.5 w-12 rounded-full transition-colors ${
107
- s <= step ? "bg-terminal" : "bg-terminal/20"
108
- }`}
99
+ className={`h-1.5 w-12 rounded-full transition-colors ${s <= step ? "bg-terminal" : "bg-terminal/20"}`}
109
100
  />
110
101
  ))}
111
102
  </div>
@@ -170,9 +161,7 @@ export default function OnboardingPage() {
170
161
  <CardTitle className="text-sm font-medium uppercase tracking-widest text-terminal">
171
162
  Pick a preset
172
163
  </CardTitle>
173
- <CardDescription>
174
- Choose a starting configuration. You can customize everything later.
175
- </CardDescription>
164
+ <CardDescription>Choose a starting configuration. You can customize everything later.</CardDescription>
176
165
  </CardHeader>
177
166
  <CardContent className="space-y-2">
178
167
  {presets
@@ -240,9 +229,7 @@ export default function OnboardingPage() {
240
229
  {selectedPresetData && selectedPresetData.channels.length > 0 && (
241
230
  <div className="flex items-center justify-between rounded-sm border border-terminal/10 px-3 py-2">
242
231
  <span className="text-muted-foreground">Channels</span>
243
- <span className="font-medium text-terminal">
244
- {selectedPresetData.channels.join(", ")}
245
- </span>
232
+ <span className="font-medium text-terminal">{selectedPresetData.channels.join(", ")}</span>
246
233
  </div>
247
234
  )}
248
235
  </CardContent>
@@ -250,11 +237,7 @@ export default function OnboardingPage() {
250
237
  <Button variant="ghost" size="sm" onClick={() => setStep(1)}>
251
238
  Back
252
239
  </Button>
253
- <Button
254
- data-onboarding-id="onboarding.launch"
255
- variant="terminal"
256
- onClick={handleLaunch}
257
- >
240
+ <Button data-onboarding-id="onboarding.launch" variant="terminal" onClick={handleLaunch}>
258
241
  Launch <Rocket className="ml-1 size-4" />
259
242
  </Button>
260
243
  </CardFooter>
@@ -105,12 +105,7 @@ export default function AccountPage() {
105
105
  {usage.instancesRunning} of {usage.instanceCap} instances used
106
106
  </span>
107
107
  </div>
108
- <Button
109
- variant="terminal"
110
- size="sm"
111
- onClick={handleManageBilling}
112
- disabled={portalLoading}
113
- >
108
+ <Button variant="terminal" size="sm" onClick={handleManageBilling} disabled={portalLoading}>
114
109
  {portalLoading ? "Redirecting..." : "Manage Billing"}
115
110
  </Button>
116
111
  </CardContent>
@@ -3,22 +3,9 @@
3
3
  import { useCallback, useEffect, useRef, useState } from "react";
4
4
  import { Button } from "@/components/ui/button";
5
5
  import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
6
- import {
7
- Select,
8
- SelectContent,
9
- SelectItem,
10
- SelectTrigger,
11
- SelectValue,
12
- } from "@/components/ui/select";
6
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
13
7
  import { Skeleton } from "@/components/ui/skeleton";
14
- import {
15
- Table,
16
- TableBody,
17
- TableCell,
18
- TableHead,
19
- TableHeader,
20
- TableRow,
21
- } from "@/components/ui/table";
8
+ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
22
9
  import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
23
10
  import type { AuditLogResponse } from "@/lib/api";
24
11
  import { fetchAuditLog } from "@/lib/api";
@@ -82,9 +69,7 @@ export default function ActivityPage() {
82
69
  const reqId = ++requestIdRef.current;
83
70
  try {
84
71
  const since =
85
- dateRange === "all"
86
- ? undefined
87
- : new Date(Date.now() - Number(dateRange) * 86400000).toISOString();
72
+ dateRange === "all" ? undefined : new Date(Date.now() - Number(dateRange) * 86400000).toISOString();
88
73
  const result = await fetchAuditLog({
89
74
  limit: PAGE_SIZE,
90
75
  offset: newOffset,
@@ -134,9 +119,7 @@ export default function ActivityPage() {
134
119
  <div className="flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
135
120
  <div>
136
121
  <CardTitle>Events</CardTitle>
137
- <CardDescription>
138
- {data ? `${data.total} total events` : "Loading..."}
139
- </CardDescription>
122
+ <CardDescription>{data ? `${data.total} total events` : "Loading..."}</CardDescription>
140
123
  </div>
141
124
  <div className="flex flex-wrap items-center gap-2">
142
125
  <Select value={dateRange} onValueChange={setDateRange}>
@@ -213,27 +196,18 @@ export default function ActivityPage() {
213
196
  </TableHeader>
214
197
  <TableBody>
215
198
  {events.map((event) => (
216
- <TableRow
217
- key={event.id}
218
- className="hover:bg-accent/50 transition-colors duration-150"
219
- >
199
+ <TableRow key={event.id} className="hover:bg-accent/50 transition-colors duration-150">
220
200
  <TableCell className="w-[100px]">
221
201
  <Tooltip>
222
202
  <TooltipTrigger className="text-xs text-muted-foreground">
223
203
  {relativeTime(event.createdAt)}
224
204
  </TooltipTrigger>
225
- <TooltipContent>
226
- {new Date(event.createdAt).toLocaleString()}
227
- </TooltipContent>
205
+ <TooltipContent>{new Date(event.createdAt).toLocaleString()}</TooltipContent>
228
206
  </Tooltip>
229
207
  </TableCell>
230
- <TableCell className="font-medium text-foreground">
231
- {humanAction(event.action)}
232
- </TableCell>
208
+ <TableCell className="font-medium text-foreground">{humanAction(event.action)}</TableCell>
233
209
  <TableCell className="text-muted-foreground">
234
- <span className="text-xs uppercase tracking-wide">
235
- {event.resourceType}
236
- </span>{" "}
210
+ <span className="text-xs uppercase tracking-wide">{event.resourceType}</span>{" "}
237
211
  {event.resourceName ?? event.resourceId}
238
212
  </TableCell>
239
213
  <TableCell className="text-xs text-muted-foreground max-w-[200px] truncate">