create-blitzpack 0.1.0 → 0.1.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 (259) hide show
  1. package/dist/index.js +35 -77
  2. package/package.json +5 -6
  3. package/template/.dockerignore +0 -59
  4. package/template/.github/workflows/ci.yml +0 -157
  5. package/template/.husky/pre-commit +0 -1
  6. package/template/.husky/pre-push +0 -1
  7. package/template/.lintstagedrc.cjs +0 -4
  8. package/template/.nvmrc +0 -1
  9. package/template/.prettierrc +0 -9
  10. package/template/.vscode/settings.json +0 -13
  11. package/template/CLAUDE.md +0 -175
  12. package/template/CONTRIBUTING.md +0 -32
  13. package/template/Dockerfile +0 -90
  14. package/template/GETTING_STARTED.md +0 -35
  15. package/template/LICENSE +0 -21
  16. package/template/README.md +0 -116
  17. package/template/apps/api/.dockerignore +0 -51
  18. package/template/apps/api/.env.local.example +0 -62
  19. package/template/apps/api/emails/account-deleted-email.tsx +0 -69
  20. package/template/apps/api/emails/components/email-layout.tsx +0 -154
  21. package/template/apps/api/emails/config.ts +0 -22
  22. package/template/apps/api/emails/password-changed-email.tsx +0 -88
  23. package/template/apps/api/emails/password-reset-email.tsx +0 -86
  24. package/template/apps/api/emails/verification-email.tsx +0 -85
  25. package/template/apps/api/emails/welcome-email.tsx +0 -70
  26. package/template/apps/api/package.json +0 -84
  27. package/template/apps/api/prisma/migrations/20251012111439_init/migration.sql +0 -13
  28. package/template/apps/api/prisma/migrations/20251018162629_add_better_auth_fields/migration.sql +0 -67
  29. package/template/apps/api/prisma/migrations/20251019142208_add_user_role_enum/migration.sql +0 -5
  30. package/template/apps/api/prisma/migrations/20251019182151_user_auth/migration.sql +0 -7
  31. package/template/apps/api/prisma/migrations/20251019211416_faster_session_lookup/migration.sql +0 -2
  32. package/template/apps/api/prisma/migrations/20251119124337_add_upload_model/migration.sql +0 -26
  33. package/template/apps/api/prisma/migrations/20251120071241_add_scope_to_account/migration.sql +0 -2
  34. package/template/apps/api/prisma/migrations/20251120072608_add_oauth_token_expiration_fields/migration.sql +0 -10
  35. package/template/apps/api/prisma/migrations/20251120144705_add_audit_logs/migration.sql +0 -29
  36. package/template/apps/api/prisma/migrations/20251127123614_remove_impersonated_by/migration.sql +0 -8
  37. package/template/apps/api/prisma/migrations/20251127125630_remove_audit_logs/migration.sql +0 -11
  38. package/template/apps/api/prisma/migrations/migration_lock.toml +0 -3
  39. package/template/apps/api/prisma/schema.prisma +0 -116
  40. package/template/apps/api/prisma/seed.ts +0 -159
  41. package/template/apps/api/prisma.config.ts +0 -14
  42. package/template/apps/api/src/app.ts +0 -377
  43. package/template/apps/api/src/common/logger.service.ts +0 -227
  44. package/template/apps/api/src/config/env.ts +0 -60
  45. package/template/apps/api/src/config/rate-limit.ts +0 -29
  46. package/template/apps/api/src/hooks/auth.ts +0 -122
  47. package/template/apps/api/src/plugins/auth.ts +0 -198
  48. package/template/apps/api/src/plugins/database.ts +0 -45
  49. package/template/apps/api/src/plugins/logger.ts +0 -33
  50. package/template/apps/api/src/plugins/multipart.ts +0 -16
  51. package/template/apps/api/src/plugins/scalar.ts +0 -20
  52. package/template/apps/api/src/plugins/schedule.ts +0 -52
  53. package/template/apps/api/src/plugins/services.ts +0 -66
  54. package/template/apps/api/src/plugins/swagger.ts +0 -56
  55. package/template/apps/api/src/routes/accounts.ts +0 -91
  56. package/template/apps/api/src/routes/admin-sessions.ts +0 -92
  57. package/template/apps/api/src/routes/metrics.ts +0 -71
  58. package/template/apps/api/src/routes/password.ts +0 -46
  59. package/template/apps/api/src/routes/sessions.ts +0 -53
  60. package/template/apps/api/src/routes/stats.ts +0 -38
  61. package/template/apps/api/src/routes/uploads-serve.ts +0 -27
  62. package/template/apps/api/src/routes/uploads.ts +0 -154
  63. package/template/apps/api/src/routes/users.ts +0 -114
  64. package/template/apps/api/src/routes/verification.ts +0 -90
  65. package/template/apps/api/src/server.ts +0 -34
  66. package/template/apps/api/src/services/accounts.service.ts +0 -125
  67. package/template/apps/api/src/services/authorization.service.ts +0 -162
  68. package/template/apps/api/src/services/email.service.ts +0 -170
  69. package/template/apps/api/src/services/file-storage.service.ts +0 -267
  70. package/template/apps/api/src/services/metrics.service.ts +0 -175
  71. package/template/apps/api/src/services/password.service.ts +0 -56
  72. package/template/apps/api/src/services/sessions.service.spec.ts +0 -134
  73. package/template/apps/api/src/services/sessions.service.ts +0 -276
  74. package/template/apps/api/src/services/stats.service.ts +0 -273
  75. package/template/apps/api/src/services/uploads.service.ts +0 -163
  76. package/template/apps/api/src/services/users.service.spec.ts +0 -249
  77. package/template/apps/api/src/services/users.service.ts +0 -198
  78. package/template/apps/api/src/utils/file-validation.ts +0 -108
  79. package/template/apps/api/start.sh +0 -33
  80. package/template/apps/api/test/helpers/fastify-app.ts +0 -24
  81. package/template/apps/api/test/helpers/mock-authorization.ts +0 -16
  82. package/template/apps/api/test/helpers/mock-logger.ts +0 -28
  83. package/template/apps/api/test/helpers/mock-prisma.ts +0 -30
  84. package/template/apps/api/test/helpers/test-db.ts +0 -125
  85. package/template/apps/api/test/integration/auth-flow.integration.spec.ts +0 -449
  86. package/template/apps/api/test/integration/password.integration.spec.ts +0 -427
  87. package/template/apps/api/test/integration/rate-limit.integration.spec.ts +0 -51
  88. package/template/apps/api/test/integration/sessions.integration.spec.ts +0 -445
  89. package/template/apps/api/test/integration/users.integration.spec.ts +0 -211
  90. package/template/apps/api/test/setup.ts +0 -31
  91. package/template/apps/api/tsconfig.json +0 -26
  92. package/template/apps/api/vitest.config.ts +0 -35
  93. package/template/apps/web/.env.local.example +0 -11
  94. package/template/apps/web/components.json +0 -24
  95. package/template/apps/web/next.config.ts +0 -22
  96. package/template/apps/web/package.json +0 -56
  97. package/template/apps/web/postcss.config.js +0 -5
  98. package/template/apps/web/public/apple-icon.png +0 -0
  99. package/template/apps/web/public/icon.png +0 -0
  100. package/template/apps/web/public/robots.txt +0 -3
  101. package/template/apps/web/src/app/(admin)/admin/layout.tsx +0 -222
  102. package/template/apps/web/src/app/(admin)/admin/page.tsx +0 -157
  103. package/template/apps/web/src/app/(admin)/admin/sessions/page.tsx +0 -18
  104. package/template/apps/web/src/app/(admin)/admin/users/page.tsx +0 -20
  105. package/template/apps/web/src/app/(auth)/forgot-password/page.tsx +0 -177
  106. package/template/apps/web/src/app/(auth)/login/page.tsx +0 -159
  107. package/template/apps/web/src/app/(auth)/reset-password/page.tsx +0 -245
  108. package/template/apps/web/src/app/(auth)/signup/page.tsx +0 -153
  109. package/template/apps/web/src/app/dashboard/change-password/page.tsx +0 -255
  110. package/template/apps/web/src/app/dashboard/page.tsx +0 -296
  111. package/template/apps/web/src/app/error.tsx +0 -32
  112. package/template/apps/web/src/app/examples/file-upload/page.tsx +0 -200
  113. package/template/apps/web/src/app/favicon.ico +0 -0
  114. package/template/apps/web/src/app/global-error.tsx +0 -96
  115. package/template/apps/web/src/app/globals.css +0 -22
  116. package/template/apps/web/src/app/icon.png +0 -0
  117. package/template/apps/web/src/app/layout.tsx +0 -34
  118. package/template/apps/web/src/app/not-found.tsx +0 -28
  119. package/template/apps/web/src/app/page.tsx +0 -192
  120. package/template/apps/web/src/components/admin/activity-feed.tsx +0 -101
  121. package/template/apps/web/src/components/admin/charts/auth-breakdown-chart.tsx +0 -114
  122. package/template/apps/web/src/components/admin/charts/chart-tooltip.tsx +0 -124
  123. package/template/apps/web/src/components/admin/charts/realtime-metrics-chart.tsx +0 -511
  124. package/template/apps/web/src/components/admin/charts/role-distribution-chart.tsx +0 -102
  125. package/template/apps/web/src/components/admin/charts/session-activity-chart.tsx +0 -90
  126. package/template/apps/web/src/components/admin/charts/user-growth-chart.tsx +0 -108
  127. package/template/apps/web/src/components/admin/health-indicator.tsx +0 -175
  128. package/template/apps/web/src/components/admin/refresh-control.tsx +0 -90
  129. package/template/apps/web/src/components/admin/session-revoke-all-dialog.tsx +0 -79
  130. package/template/apps/web/src/components/admin/session-revoke-dialog.tsx +0 -74
  131. package/template/apps/web/src/components/admin/sessions-management-table.tsx +0 -372
  132. package/template/apps/web/src/components/admin/stat-card.tsx +0 -137
  133. package/template/apps/web/src/components/admin/user-create-dialog.tsx +0 -152
  134. package/template/apps/web/src/components/admin/user-delete-dialog.tsx +0 -73
  135. package/template/apps/web/src/components/admin/user-edit-dialog.tsx +0 -170
  136. package/template/apps/web/src/components/admin/users-management-table.tsx +0 -285
  137. package/template/apps/web/src/components/auth/email-verification-banner.tsx +0 -85
  138. package/template/apps/web/src/components/auth/github-button.tsx +0 -40
  139. package/template/apps/web/src/components/auth/google-button.tsx +0 -54
  140. package/template/apps/web/src/components/auth/protected-route.tsx +0 -66
  141. package/template/apps/web/src/components/auth/redirect-if-authenticated.tsx +0 -31
  142. package/template/apps/web/src/components/auth/with-auth.tsx +0 -30
  143. package/template/apps/web/src/components/error/error-card.tsx +0 -47
  144. package/template/apps/web/src/components/error/forbidden.tsx +0 -25
  145. package/template/apps/web/src/components/landing/command-block.tsx +0 -64
  146. package/template/apps/web/src/components/landing/feature-card.tsx +0 -60
  147. package/template/apps/web/src/components/landing/included-feature-card.tsx +0 -63
  148. package/template/apps/web/src/components/landing/logo.tsx +0 -41
  149. package/template/apps/web/src/components/landing/tech-badge.tsx +0 -11
  150. package/template/apps/web/src/components/layout/auth-nav.tsx +0 -58
  151. package/template/apps/web/src/components/layout/footer.tsx +0 -3
  152. package/template/apps/web/src/config/landing-data.ts +0 -152
  153. package/template/apps/web/src/config/site.ts +0 -5
  154. package/template/apps/web/src/hooks/api/__tests__/use-users.test.tsx +0 -181
  155. package/template/apps/web/src/hooks/api/use-admin-sessions.ts +0 -75
  156. package/template/apps/web/src/hooks/api/use-admin-stats.ts +0 -33
  157. package/template/apps/web/src/hooks/api/use-sessions.ts +0 -52
  158. package/template/apps/web/src/hooks/api/use-uploads.ts +0 -156
  159. package/template/apps/web/src/hooks/api/use-users.ts +0 -149
  160. package/template/apps/web/src/hooks/use-mobile.ts +0 -21
  161. package/template/apps/web/src/hooks/use-realtime-metrics.ts +0 -120
  162. package/template/apps/web/src/lib/__tests__/utils.test.ts +0 -29
  163. package/template/apps/web/src/lib/api.ts +0 -151
  164. package/template/apps/web/src/lib/auth.ts +0 -13
  165. package/template/apps/web/src/lib/env.ts +0 -52
  166. package/template/apps/web/src/lib/form-utils.ts +0 -11
  167. package/template/apps/web/src/lib/utils.ts +0 -1
  168. package/template/apps/web/src/providers.tsx +0 -34
  169. package/template/apps/web/src/store/atoms.ts +0 -15
  170. package/template/apps/web/src/test/helpers/test-utils.tsx +0 -44
  171. package/template/apps/web/src/test/setup.ts +0 -8
  172. package/template/apps/web/tailwind.config.ts +0 -5
  173. package/template/apps/web/tsconfig.json +0 -26
  174. package/template/apps/web/vitest.config.ts +0 -32
  175. package/template/assets/logo-512.png +0 -0
  176. package/template/assets/logo.svg +0 -4
  177. package/template/docker-compose.prod.yml +0 -66
  178. package/template/docker-compose.yml +0 -36
  179. package/template/eslint.config.ts +0 -119
  180. package/template/package.json +0 -77
  181. package/template/packages/tailwind-config/package.json +0 -9
  182. package/template/packages/tailwind-config/theme.css +0 -179
  183. package/template/packages/types/package.json +0 -29
  184. package/template/packages/types/src/__tests__/schemas.test.ts +0 -255
  185. package/template/packages/types/src/api-response.ts +0 -53
  186. package/template/packages/types/src/health-check.ts +0 -11
  187. package/template/packages/types/src/pagination.ts +0 -41
  188. package/template/packages/types/src/role.ts +0 -5
  189. package/template/packages/types/src/session.ts +0 -48
  190. package/template/packages/types/src/stats.ts +0 -113
  191. package/template/packages/types/src/upload.ts +0 -51
  192. package/template/packages/types/src/user.ts +0 -36
  193. package/template/packages/types/tsconfig.json +0 -5
  194. package/template/packages/types/vitest.config.ts +0 -21
  195. package/template/packages/ui/components.json +0 -21
  196. package/template/packages/ui/package.json +0 -108
  197. package/template/packages/ui/src/__tests__/button.test.tsx +0 -70
  198. package/template/packages/ui/src/alert-dialog.tsx +0 -141
  199. package/template/packages/ui/src/alert.tsx +0 -66
  200. package/template/packages/ui/src/animated-theme-toggler.tsx +0 -167
  201. package/template/packages/ui/src/avatar.tsx +0 -53
  202. package/template/packages/ui/src/badge.tsx +0 -36
  203. package/template/packages/ui/src/button.tsx +0 -84
  204. package/template/packages/ui/src/card.tsx +0 -92
  205. package/template/packages/ui/src/checkbox.tsx +0 -32
  206. package/template/packages/ui/src/data-table/data-table-column-header.tsx +0 -68
  207. package/template/packages/ui/src/data-table/data-table-pagination.tsx +0 -99
  208. package/template/packages/ui/src/data-table/data-table-toolbar.tsx +0 -55
  209. package/template/packages/ui/src/data-table/data-table-view-options.tsx +0 -63
  210. package/template/packages/ui/src/data-table/data-table.tsx +0 -167
  211. package/template/packages/ui/src/dialog.tsx +0 -143
  212. package/template/packages/ui/src/dropdown-menu.tsx +0 -257
  213. package/template/packages/ui/src/empty-state.tsx +0 -52
  214. package/template/packages/ui/src/file-upload-input.tsx +0 -202
  215. package/template/packages/ui/src/form.tsx +0 -168
  216. package/template/packages/ui/src/hooks/use-mobile.ts +0 -19
  217. package/template/packages/ui/src/icons/brand-icons.tsx +0 -16
  218. package/template/packages/ui/src/input.tsx +0 -21
  219. package/template/packages/ui/src/label.tsx +0 -24
  220. package/template/packages/ui/src/lib/utils.ts +0 -6
  221. package/template/packages/ui/src/password-input.tsx +0 -102
  222. package/template/packages/ui/src/popover.tsx +0 -48
  223. package/template/packages/ui/src/radio-group.tsx +0 -45
  224. package/template/packages/ui/src/scroll-area.tsx +0 -58
  225. package/template/packages/ui/src/select.tsx +0 -187
  226. package/template/packages/ui/src/separator.tsx +0 -28
  227. package/template/packages/ui/src/sheet.tsx +0 -139
  228. package/template/packages/ui/src/sidebar.tsx +0 -726
  229. package/template/packages/ui/src/skeleton-variants.tsx +0 -87
  230. package/template/packages/ui/src/skeleton.tsx +0 -13
  231. package/template/packages/ui/src/slider.tsx +0 -63
  232. package/template/packages/ui/src/sonner.tsx +0 -25
  233. package/template/packages/ui/src/spinner.tsx +0 -16
  234. package/template/packages/ui/src/switch.tsx +0 -31
  235. package/template/packages/ui/src/table.tsx +0 -116
  236. package/template/packages/ui/src/tabs.tsx +0 -66
  237. package/template/packages/ui/src/textarea.tsx +0 -18
  238. package/template/packages/ui/src/tooltip.tsx +0 -61
  239. package/template/packages/ui/src/user-avatar.tsx +0 -97
  240. package/template/packages/ui/test-config.js +0 -3
  241. package/template/packages/ui/tsconfig.json +0 -12
  242. package/template/packages/ui/turbo.json +0 -18
  243. package/template/packages/ui/vitest.config.ts +0 -17
  244. package/template/packages/ui/vitest.setup.ts +0 -1
  245. package/template/packages/utils/package.json +0 -23
  246. package/template/packages/utils/src/__tests__/utils.test.ts +0 -223
  247. package/template/packages/utils/src/array.ts +0 -18
  248. package/template/packages/utils/src/async.ts +0 -3
  249. package/template/packages/utils/src/date.ts +0 -77
  250. package/template/packages/utils/src/errors.ts +0 -73
  251. package/template/packages/utils/src/number.ts +0 -11
  252. package/template/packages/utils/src/string.ts +0 -13
  253. package/template/packages/utils/tsconfig.json +0 -5
  254. package/template/packages/utils/vitest.config.ts +0 -21
  255. package/template/pnpm-workspace.yaml +0 -4
  256. package/template/tsconfig.base.json +0 -32
  257. package/template/turbo.json +0 -133
  258. package/template/vitest.shared.ts +0 -26
  259. package/template/vitest.workspace.ts +0 -9
@@ -1,35 +0,0 @@
1
- import tsconfigPaths from 'vite-tsconfig-paths';
2
- import { defineConfig, mergeConfig } from 'vitest/config';
3
-
4
- import { sharedConfig } from '../../vitest.shared';
5
-
6
- export default mergeConfig(
7
- sharedConfig,
8
- defineConfig({
9
- test: {
10
- name: '@repo/api',
11
- include: [
12
- 'src/**/*.spec.ts', // Unit tests (with mocks)
13
- 'test/**/*.spec.ts', // Unit tests
14
- 'test/**/*.integration.spec.ts', // Integration tests (with real DB)
15
- ],
16
- globals: true,
17
- root: './',
18
- setupFiles: ['./test/setup.ts'],
19
- // Run tests sequentially for integration tests (shared DB)
20
- fileParallelism: false, // Disable file-level parallelism
21
- sequence: {
22
- concurrent: false, // Disable test-level parallelism
23
- },
24
- coverage: {
25
- thresholds: {
26
- lines: 80,
27
- functions: 80,
28
- branches: 75,
29
- statements: 80,
30
- },
31
- },
32
- },
33
- plugins: [tsconfigPaths()],
34
- })
35
- );
@@ -1,11 +0,0 @@
1
- NODE_ENV=development
2
-
3
- # CRITICAL: Must include /api at the end (all API routes are under /api prefix)
4
- # The auth client and regular API client both use this base URL
5
- # Auth routes: {NEXT_PUBLIC_API_URL}/auth/*
6
- # Other routes: {NEXT_PUBLIC_API_URL}/*
7
- #
8
- # Examples:
9
- # Local: http://localhost:8080/api
10
- # Production: https://your-railway-api.up.railway.app/api
11
- NEXT_PUBLIC_API_URL=http://localhost:8080/api
@@ -1,24 +0,0 @@
1
- {
2
- "$schema": "https://ui.shadcn.com/schema.json",
3
- "style": "new-york",
4
- "rsc": true,
5
- "tsx": true,
6
- "tailwind": {
7
- "config": "",
8
- "css": "src/app/globals.css",
9
- "baseColor": "neutral",
10
- "cssVariables": true,
11
- "prefix": ""
12
- },
13
- "iconLibrary": "lucide",
14
- "aliases": {
15
- "components": "@/components",
16
- "utils": "@/lib/utils",
17
- "ui": "@/components/ui",
18
- "lib": "@/lib",
19
- "hooks": "@/hooks"
20
- },
21
- "registries": {
22
- "@magicui": "https://magicui.design/r/{name}.json"
23
- }
24
- }
@@ -1,22 +0,0 @@
1
- import type { NextConfig } from 'next';
2
-
3
- const nextConfig: NextConfig = {
4
- transpilePackages: ['@repo/packages-types', '@repo/packages-utils'],
5
- compiler: {
6
- removeConsole: process.env.NODE_ENV === 'production',
7
- },
8
- images: {
9
- remotePatterns: [
10
- {
11
- protocol: 'https',
12
- hostname: 'lh3.googleusercontent.com',
13
- },
14
- {
15
- protocol: 'https',
16
- hostname: 'avatars.githubusercontent.com',
17
- },
18
- ],
19
- },
20
- };
21
-
22
- export default nextConfig;
@@ -1,56 +0,0 @@
1
- {
2
- "name": "@repo/web",
3
- "version": "1.0.0",
4
- "private": true,
5
- "scripts": {
6
- "dev": "next dev",
7
- "build": "next build",
8
- "start": "next start",
9
- "typecheck": "tsc --noEmit",
10
- "lint": "eslint .",
11
- "lint:fix": "eslint --fix .",
12
- "test": "vitest run",
13
- "test:unit": "vitest run",
14
- "test:integration": "echo 'No integration tests for web'",
15
- "test:watch": "vitest",
16
- "test:coverage": "vitest run --coverage",
17
- "vercel-build": "cd ../.. && turbo build --filter=@repo/web",
18
- "vercel-ignore-build": "npx turbo-ignore --fallback=HEAD^1"
19
- },
20
- "dependencies": {
21
- "@hookform/resolvers": "^5.2.2",
22
- "@repo/packages-types": "workspace:*",
23
- "@repo/packages-ui": "workspace:*",
24
- "@repo/packages-utils": "workspace:*",
25
- "@tanstack/react-query": "^5.90.2",
26
- "@tanstack/react-table": "^8.21.3",
27
- "better-auth": "^1.3.27",
28
- "date-fns": "^4.1.0",
29
- "framer-motion": "^12.23.24",
30
- "jotai": "^2.15.0",
31
- "lucide-react": "^0.545.0",
32
- "next": "16.0.3",
33
- "next-themes": "^0.4.6",
34
- "react": "19.2.0",
35
- "react-dom": "19.2.0",
36
- "react-hook-form": "^7.65.0",
37
- "recharts": "^3.5.0",
38
- "sonner": "^2.0.7",
39
- "zod": "^4.1.12"
40
- },
41
- "devDependencies": {
42
- "@repo/tailwind-config": "workspace:*",
43
- "@tailwindcss/postcss": "^4.1.14",
44
- "@types/node": "^24.7.1",
45
- "@types/react": "19.2.6",
46
- "@types/react-dom": "19.2.3",
47
- "@vitejs/plugin-react": "^5.0.4",
48
- "eslint": "^9.18.0",
49
- "eslint-config-next": "16.0.3",
50
- "tailwindcss": "^4.1.14",
51
- "tailwindcss-debug-screens": "^3.0.1",
52
- "tw-animate-css": "^1.4.0",
53
- "typescript": "^5.7.2",
54
- "vitest": "^3.2.4"
55
- }
56
- }
@@ -1,5 +0,0 @@
1
- module.exports = {
2
- plugins: {
3
- '@tailwindcss/postcss': {},
4
- },
5
- };
Binary file
@@ -1,3 +0,0 @@
1
- # https://www.robotstxt.org/robotstxt.html
2
- User-agent: *
3
- Disallow:
@@ -1,222 +0,0 @@
1
- 'use client';
2
-
3
- import { AnimatedThemeToggler } from '@repo/packages-ui/animated-theme-toggler';
4
- import {
5
- DropdownMenu,
6
- DropdownMenuContent,
7
- DropdownMenuItem,
8
- DropdownMenuTrigger,
9
- } from '@repo/packages-ui/dropdown-menu';
10
- import {
11
- Sidebar,
12
- SidebarContent,
13
- SidebarFooter,
14
- SidebarGroup,
15
- SidebarGroupContent,
16
- SidebarGroupLabel,
17
- SidebarHeader,
18
- SidebarInset,
19
- SidebarMenu,
20
- SidebarMenuButton,
21
- SidebarMenuItem,
22
- SidebarProvider,
23
- SidebarTrigger,
24
- } from '@repo/packages-ui/sidebar';
25
- import { UserAvatar } from '@repo/packages-ui/user-avatar';
26
- import { motion } from 'framer-motion';
27
- import {
28
- ChevronsUpDown,
29
- KeyRound,
30
- LogOut,
31
- MonitorCheck,
32
- ShieldCheck,
33
- Users,
34
- } from 'lucide-react';
35
- import Link from 'next/link';
36
- import { usePathname, useRouter } from 'next/navigation';
37
- import React, { type ReactNode } from 'react';
38
-
39
- import { ProtectedRoute } from '@/components/auth/protected-route';
40
- import { authClient } from '@/lib/auth';
41
-
42
- const adminNavItems = [
43
- {
44
- title: 'System Monitoring',
45
- href: '/admin',
46
- icon: MonitorCheck,
47
- },
48
- {
49
- title: 'Users',
50
- href: '/admin/users',
51
- icon: Users,
52
- },
53
- {
54
- title: 'Sessions',
55
- href: '/admin/sessions',
56
- icon: KeyRound,
57
- },
58
- ];
59
-
60
- function AdminLayoutContent({ children }: { children: ReactNode }) {
61
- const pathname = usePathname();
62
- const router = useRouter();
63
- const { data: session } = authClient.useSession();
64
-
65
- const handleSignOut = async () => {
66
- await authClient.signOut();
67
- router.push('/');
68
- };
69
-
70
- return (
71
- <SidebarProvider>
72
- <Sidebar collapsible="icon">
73
- <SidebarHeader>
74
- <SidebarMenu>
75
- <SidebarMenuItem>
76
- <SidebarMenuButton
77
- size="lg"
78
- className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
79
- >
80
- <div className="bg-primary text-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg">
81
- <ShieldCheck className="size-4" />
82
- </div>
83
- <div className="grid flex-1 text-left text-sm leading-tight">
84
- <span className="truncate font-semibold">Admin Panel</span>
85
- <span className="truncate text-xs">Manage App</span>
86
- </div>
87
- </SidebarMenuButton>
88
- </SidebarMenuItem>
89
- </SidebarMenu>
90
- </SidebarHeader>
91
- <SidebarContent>
92
- <SidebarGroup>
93
- <SidebarGroupLabel>Navigation</SidebarGroupLabel>
94
- <SidebarGroupContent>
95
- <SidebarMenu>
96
- {adminNavItems.map((item) => {
97
- const Icon = item.icon;
98
- const isActive = pathname === item.href;
99
-
100
- return (
101
- <SidebarMenuItem key={item.href}>
102
- <SidebarMenuButton
103
- asChild
104
- isActive={isActive}
105
- tooltip={item.title}
106
- className="hover:bg-sidebar-accent/50 relative overflow-visible data-[active=true]:bg-transparent"
107
- >
108
- <Link href={item.href} className="relative z-20">
109
- {isActive && (
110
- <motion.div
111
- layoutId="active-nav-item"
112
- className="bg-sidebar-primary absolute inset-0 -z-10 rounded-md"
113
- transition={{
114
- type: 'spring',
115
- stiffness: 300,
116
- damping: 30,
117
- }}
118
- />
119
- )}
120
- <motion.span
121
- animate={{
122
- color: isActive
123
- ? 'var(--sidebar-primary-foreground)'
124
- : 'var(--sidebar-foreground)',
125
- }}
126
- transition={{
127
- duration: 0.2,
128
- delay: isActive ? 0.1 : 0,
129
- }}
130
- className="flex items-center justify-center"
131
- >
132
- <Icon className="size-4" />
133
- </motion.span>
134
- <motion.span
135
- animate={{
136
- color: isActive
137
- ? 'var(--sidebar-primary-foreground)'
138
- : 'var(--sidebar-foreground)',
139
- }}
140
- transition={{
141
- duration: 0.2,
142
- delay: isActive ? 0.1 : 0,
143
- }}
144
- className="truncate"
145
- >
146
- {item.title}
147
- </motion.span>
148
- </Link>
149
- </SidebarMenuButton>
150
- </SidebarMenuItem>
151
- );
152
- })}
153
- </SidebarMenu>
154
- </SidebarGroupContent>
155
- </SidebarGroup>
156
- </SidebarContent>
157
- <SidebarFooter>
158
- <SidebarMenu>
159
- <SidebarMenuItem>
160
- <DropdownMenu>
161
- <DropdownMenuTrigger asChild>
162
- <SidebarMenuButton
163
- size="lg"
164
- className="data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground"
165
- >
166
- <UserAvatar
167
- src={session?.user.image}
168
- name={session?.user.name}
169
- email={session?.user.email}
170
- size="sm"
171
- className="rounded-lg"
172
- />
173
- <div className="grid flex-1 text-left text-sm leading-tight">
174
- <span className="truncate font-semibold">
175
- {session?.user.name || 'Admin'}
176
- </span>
177
- <span className="truncate text-xs">
178
- {session?.user.email}
179
- </span>
180
- </div>
181
- <ChevronsUpDown className="ml-auto size-4" />
182
- </SidebarMenuButton>
183
- </DropdownMenuTrigger>
184
- <DropdownMenuContent
185
- className="w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg"
186
- side="bottom"
187
- align="end"
188
- sideOffset={4}
189
- >
190
- <DropdownMenuItem onClick={handleSignOut}>
191
- <LogOut className="mr-2 size-4" />
192
- Log out
193
- </DropdownMenuItem>
194
- </DropdownMenuContent>
195
- </DropdownMenu>
196
- </SidebarMenuItem>
197
- </SidebarMenu>
198
- </SidebarFooter>
199
- </Sidebar>
200
- <SidebarInset>
201
- <header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
202
- <SidebarTrigger className="-ml-1" />
203
- <div className="flex-1" />
204
- <AnimatedThemeToggler />
205
- </header>
206
- <div className="flex flex-1 flex-col gap-4 p-4 pt-0">{children}</div>
207
- </SidebarInset>
208
- </SidebarProvider>
209
- );
210
- }
211
-
212
- export default function AdminLayout({
213
- children,
214
- }: {
215
- children: React.ReactNode;
216
- }) {
217
- return (
218
- <ProtectedRoute requiredRole="admin" redirectTo="/dashboard">
219
- <AdminLayoutContent>{children}</AdminLayoutContent>
220
- </ProtectedRoute>
221
- );
222
- }
@@ -1,157 +0,0 @@
1
- 'use client';
2
-
3
- import { Activity, CalendarDays, UserPlus, Users } from 'lucide-react';
4
- import { useCallback, useState } from 'react';
5
-
6
- import {
7
- ActivityFeedSkeleton,
8
- RecentSignupsFeed,
9
- } from '@/components/admin/activity-feed';
10
- import {
11
- AuthBreakdownChart,
12
- AuthBreakdownChartSkeleton,
13
- } from '@/components/admin/charts/auth-breakdown-chart';
14
- import {
15
- RealtimeMetricsChart,
16
- RealtimeMetricsChartSkeleton,
17
- } from '@/components/admin/charts/realtime-metrics-chart';
18
- import {
19
- RoleDistributionChart,
20
- RoleDistributionChartSkeleton,
21
- } from '@/components/admin/charts/role-distribution-chart';
22
- import {
23
- SessionActivityChart,
24
- SessionActivityChartSkeleton,
25
- } from '@/components/admin/charts/session-activity-chart';
26
- import {
27
- UserGrowthChart,
28
- UserGrowthChartSkeleton,
29
- } from '@/components/admin/charts/user-growth-chart';
30
- import {
31
- HealthIndicator,
32
- HealthIndicatorSkeleton,
33
- } from '@/components/admin/health-indicator';
34
- import { RefreshControl } from '@/components/admin/refresh-control';
35
- import { StatCard, StatCardSkeleton } from '@/components/admin/stat-card';
36
- import { useFetchSystemStats } from '@/hooks/api/use-admin-stats';
37
-
38
- export default function AdminDashboardPage() {
39
- const [refreshInterval, setRefreshInterval] = useState<number | null>(15000);
40
- const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
41
-
42
- const { data, isLoading, isFetching, refetch } = useFetchSystemStats({
43
- refetchInterval: refreshInterval ?? false,
44
- refetchOnWindowFocus: false,
45
- });
46
-
47
- const handleRefresh = useCallback(() => {
48
- refetch().then(() => setLastUpdated(new Date()));
49
- }, [refetch]);
50
-
51
- if (data && !lastUpdated) {
52
- setLastUpdated(new Date());
53
- }
54
-
55
- return (
56
- <div className="container mx-auto space-y-6 px-6 py-8">
57
- <div className="mb-8 flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between">
58
- <div>
59
- <h1 className="mb-2 text-3xl font-bold">System Monitoring</h1>
60
- <p className="text-muted-foreground">
61
- Real-time application metrics and health status
62
- </p>
63
- </div>
64
- <RefreshControl
65
- interval={refreshInterval}
66
- onIntervalChange={setRefreshInterval}
67
- onRefresh={handleRefresh}
68
- isRefreshing={isFetching}
69
- lastUpdated={lastUpdated}
70
- />
71
- </div>
72
-
73
- <div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-4">
74
- {isLoading ? (
75
- Array.from({ length: 4 }).map((_, i) => <StatCardSkeleton key={i} />)
76
- ) : data ? (
77
- <>
78
- <StatCard
79
- title="Total Users"
80
- value={data.overview.totalUsers}
81
- icon={Users}
82
- accentColor="blue"
83
- />
84
- <StatCard
85
- title="Active Sessions (24h)"
86
- value={data.overview.activeSessionsLast24h}
87
- icon={Activity}
88
- accentColor="emerald"
89
- />
90
- <StatCard
91
- title="New Today"
92
- value={data.overview.newUsersToday}
93
- icon={UserPlus}
94
- accentColor="cyan"
95
- />
96
- <StatCard
97
- title="New This Week"
98
- value={data.overview.newUsersThisWeek}
99
- icon={CalendarDays}
100
- accentColor="amber"
101
- />
102
- </>
103
- ) : null}
104
- </div>
105
-
106
- <div className="grid gap-6 lg:grid-cols-2">
107
- {isLoading ? (
108
- <RealtimeMetricsChartSkeleton />
109
- ) : (
110
- <RealtimeMetricsChart />
111
- )}
112
- </div>
113
-
114
- <div className="grid gap-6 lg:grid-cols-2">
115
- {isLoading ? (
116
- <>
117
- <UserGrowthChartSkeleton />
118
- <SessionActivityChartSkeleton />
119
- </>
120
- ) : data ? (
121
- <>
122
- <UserGrowthChart data={data.userGrowth} />
123
- <SessionActivityChart data={data.sessionActivity} />
124
- </>
125
- ) : null}
126
- </div>
127
-
128
- <div className="grid gap-6 lg:grid-cols-2">
129
- {isLoading ? (
130
- <>
131
- <RoleDistributionChartSkeleton />
132
- <AuthBreakdownChartSkeleton />
133
- </>
134
- ) : data ? (
135
- <>
136
- <RoleDistributionChart data={data.roleDistribution} />
137
- <AuthBreakdownChart data={data.authBreakdown} />
138
- </>
139
- ) : null}
140
- </div>
141
-
142
- <div className="grid gap-6 lg:grid-cols-2">
143
- {isLoading ? (
144
- <>
145
- <ActivityFeedSkeleton />
146
- <HealthIndicatorSkeleton />
147
- </>
148
- ) : data ? (
149
- <>
150
- <RecentSignupsFeed signups={data.recentSignups} />
151
- <HealthIndicator health={data.systemHealth} />
152
- </>
153
- ) : null}
154
- </div>
155
- </div>
156
- );
157
- }
@@ -1,18 +0,0 @@
1
- 'use client';
2
-
3
- import { SessionsManagementTable } from '@/components/admin/sessions-management-table';
4
-
5
- export default function AdminSessionsPage() {
6
- return (
7
- <div className="container mx-auto space-y-6 px-6 py-8">
8
- <div className="mb-8">
9
- <h1 className="mb-2 text-3xl font-bold">Session Management</h1>
10
- <p className="text-muted-foreground">
11
- Monitor and manage user sessions across all devices
12
- </p>
13
- </div>
14
-
15
- <SessionsManagementTable />
16
- </div>
17
- );
18
- }
@@ -1,20 +0,0 @@
1
- 'use client';
2
-
3
- import React from 'react';
4
-
5
- import { UsersManagementTable } from '@/components/admin/users-management-table';
6
-
7
- export default function AdminUsersPage() {
8
- return (
9
- <div className="container mx-auto px-6 py-8">
10
- <div className="mb-8">
11
- <h1 className="mb-2 text-3xl font-bold">User Management</h1>
12
- <p className="text-muted-foreground">
13
- Manage user accounts, roles, and permissions
14
- </p>
15
- </div>
16
-
17
- <UsersManagementTable />
18
- </div>
19
- );
20
- }