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,87 +0,0 @@
1
- import { Skeleton } from './skeleton';
2
-
3
- export function SkeletonCard() {
4
- return (
5
- <div className="border-border bg-card rounded-lg border p-6">
6
- <div className="flex items-center gap-3">
7
- <Skeleton className="h-11 w-11 rounded-full" />
8
- <div className="flex-1 space-y-2">
9
- <Skeleton className="h-3 w-24" />
10
- <Skeleton className="h-5 w-32" />
11
- </div>
12
- </div>
13
- </div>
14
- );
15
- }
16
-
17
- export function SkeletonTable({ rows = 5 }: { rows?: number }) {
18
- return (
19
- <div className="space-y-3">
20
- {Array.from({ length: rows }).map((_, i) => (
21
- <div key={i} className="flex items-center gap-4">
22
- <Skeleton className="h-4 w-12" />
23
- <Skeleton className="h-4 flex-1" />
24
- <Skeleton className="h-4 w-24" />
25
- <Skeleton className="h-4 w-32" />
26
- <Skeleton className="h-8 w-20 rounded-md" />
27
- </div>
28
- ))}
29
- </div>
30
- );
31
- }
32
-
33
- export function SkeletonForm() {
34
- return (
35
- <div className="space-y-4">
36
- <div className="space-y-2">
37
- <Skeleton className="h-4 w-20" />
38
- <Skeleton className="h-10 w-full rounded-md" />
39
- </div>
40
- <div className="space-y-2">
41
- <Skeleton className="h-4 w-24" />
42
- <Skeleton className="h-10 w-full rounded-md" />
43
- </div>
44
- <div className="space-y-2">
45
- <Skeleton className="h-4 w-28" />
46
- <Skeleton className="h-10 w-full rounded-md" />
47
- </div>
48
- <Skeleton className="h-10 w-full rounded-md" />
49
- </div>
50
- );
51
- }
52
-
53
- export function SkeletonText({
54
- lines = 3,
55
- className,
56
- }: {
57
- lines?: number;
58
- className?: string;
59
- }) {
60
- return (
61
- <div className="space-y-2">
62
- {Array.from({ length: lines }).map((_, i) => (
63
- <Skeleton
64
- key={i}
65
- className={className}
66
- style={{
67
- width: i === lines - 1 ? '60%' : '100%',
68
- }}
69
- />
70
- ))}
71
- </div>
72
- );
73
- }
74
-
75
- export function SkeletonAvatar({
76
- size = 'default',
77
- }: {
78
- size?: 'sm' | 'default' | 'lg';
79
- }) {
80
- const sizeClasses = {
81
- sm: 'h-8 w-8',
82
- default: 'h-10 w-10',
83
- lg: 'h-16 w-16',
84
- };
85
-
86
- return <Skeleton className={`${sizeClasses[size]} rounded-full`} />;
87
- }
@@ -1,13 +0,0 @@
1
- import { cn } from './lib/utils';
2
-
3
- function Skeleton({ className, ...props }: React.ComponentProps<'div'>) {
4
- return (
5
- <div
6
- data-slot="skeleton"
7
- className={cn('bg-accent animate-pulse rounded-md', className)}
8
- {...props}
9
- />
10
- );
11
- }
12
-
13
- export { Skeleton };
@@ -1,63 +0,0 @@
1
- 'use client';
2
-
3
- import * as SliderPrimitive from '@radix-ui/react-slider';
4
- import * as React from 'react';
5
-
6
- import { cn } from './lib/utils';
7
-
8
- function Slider({
9
- className,
10
- defaultValue,
11
- value,
12
- min = 0,
13
- max = 100,
14
- ...props
15
- }: React.ComponentProps<typeof SliderPrimitive.Root>) {
16
- const _values = React.useMemo(
17
- () =>
18
- Array.isArray(value)
19
- ? value
20
- : Array.isArray(defaultValue)
21
- ? defaultValue
22
- : [min, max],
23
- [value, defaultValue, min, max]
24
- );
25
-
26
- return (
27
- <SliderPrimitive.Root
28
- data-slot="slider"
29
- defaultValue={defaultValue}
30
- value={value}
31
- min={min}
32
- max={max}
33
- className={cn(
34
- 'relative flex w-full touch-none select-none items-center data-[orientation=vertical]:h-full data-[orientation=vertical]:min-h-44 data-[orientation=vertical]:w-auto data-[orientation=vertical]:flex-col data-[disabled]:opacity-50',
35
- className
36
- )}
37
- {...props}
38
- >
39
- <SliderPrimitive.Track
40
- data-slot="slider-track"
41
- className={cn(
42
- 'bg-muted relative grow overflow-hidden rounded-full data-[orientation=horizontal]:h-1.5 data-[orientation=vertical]:h-full data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-1.5'
43
- )}
44
- >
45
- <SliderPrimitive.Range
46
- data-slot="slider-range"
47
- className={cn(
48
- 'bg-primary absolute data-[orientation=horizontal]:h-full data-[orientation=vertical]:w-full'
49
- )}
50
- />
51
- </SliderPrimitive.Track>
52
- {Array.from({ length: _values.length }, (_, index) => (
53
- <SliderPrimitive.Thumb
54
- data-slot="slider-thumb"
55
- key={index}
56
- className="border-primary ring-ring/50 focus-visible:outline-hidden block size-4 shrink-0 rounded-full border bg-white shadow-sm transition-[color,box-shadow] hover:ring-4 focus-visible:ring-4 disabled:pointer-events-none disabled:opacity-50"
57
- />
58
- ))}
59
- </SliderPrimitive.Root>
60
- );
61
- }
62
-
63
- export { Slider };
@@ -1,25 +0,0 @@
1
- 'use client';
2
-
3
- import { useTheme } from 'next-themes';
4
- import { Toaster as Sonner, type ToasterProps } from 'sonner';
5
-
6
- const Toaster = ({ ...props }: ToasterProps) => {
7
- const { theme = 'system' } = useTheme();
8
-
9
- return (
10
- <Sonner
11
- theme={theme as ToasterProps['theme']}
12
- className="toaster group"
13
- style={
14
- {
15
- '--normal-bg': 'var(--popover)',
16
- '--normal-text': 'var(--popover-foreground)',
17
- '--normal-border': 'var(--border)',
18
- } as React.CSSProperties
19
- }
20
- {...props}
21
- />
22
- );
23
- };
24
-
25
- export { Toaster };
@@ -1,16 +0,0 @@
1
- import { Loader2Icon } from 'lucide-react';
2
-
3
- import { cn } from './lib/utils';
4
-
5
- function Spinner({ className, ...props }: React.ComponentProps<'svg'>) {
6
- return (
7
- <Loader2Icon
8
- role="status"
9
- aria-label="Loading"
10
- className={cn('size-4 animate-spin', className)}
11
- {...props}
12
- />
13
- );
14
- }
15
-
16
- export { Spinner };
@@ -1,31 +0,0 @@
1
- 'use client';
2
-
3
- import * as SwitchPrimitive from '@radix-ui/react-switch';
4
- import * as React from 'react';
5
-
6
- import { cn } from './lib/utils';
7
-
8
- function Switch({
9
- className,
10
- ...props
11
- }: React.ComponentProps<typeof SwitchPrimitive.Root>) {
12
- return (
13
- <SwitchPrimitive.Root
14
- data-slot="switch"
15
- className={cn(
16
- 'data-[state=checked]:bg-primary data-[state=unchecked]:bg-input focus-visible:border-ring focus-visible:ring-ring/50 dark:data-[state=unchecked]:bg-input/80 shadow-xs peer inline-flex h-[1.15rem] w-8 shrink-0 cursor-pointer items-center rounded-full border border-transparent outline-none transition-all focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50',
17
- className
18
- )}
19
- {...props}
20
- >
21
- <SwitchPrimitive.Thumb
22
- data-slot="switch-thumb"
23
- className={cn(
24
- 'bg-background dark:data-[state=unchecked]:bg-foreground dark:data-[state=checked]:bg-primary-foreground pointer-events-none block size-4 rounded-full ring-0 transition-transform data-[state=checked]:translate-x-[calc(100%-2px)] data-[state=unchecked]:translate-x-0'
25
- )}
26
- />
27
- </SwitchPrimitive.Root>
28
- );
29
- }
30
-
31
- export { Switch };
@@ -1,116 +0,0 @@
1
- 'use client';
2
-
3
- import * as React from 'react';
4
-
5
- import { cn } from './lib/utils';
6
-
7
- function Table({ className, ...props }: React.ComponentProps<'table'>) {
8
- return (
9
- <div
10
- data-slot="table-container"
11
- className="relative w-full overflow-x-auto"
12
- >
13
- <table
14
- data-slot="table"
15
- className={cn('w-full caption-bottom text-sm', className)}
16
- {...props}
17
- />
18
- </div>
19
- );
20
- }
21
-
22
- function TableHeader({ className, ...props }: React.ComponentProps<'thead'>) {
23
- return (
24
- <thead
25
- data-slot="table-header"
26
- className={cn('[&_tr]:border-b', className)}
27
- {...props}
28
- />
29
- );
30
- }
31
-
32
- function TableBody({ className, ...props }: React.ComponentProps<'tbody'>) {
33
- return (
34
- <tbody
35
- data-slot="table-body"
36
- className={cn('[&_tr:last-child]:border-0', className)}
37
- {...props}
38
- />
39
- );
40
- }
41
-
42
- function TableFooter({ className, ...props }: React.ComponentProps<'tfoot'>) {
43
- return (
44
- <tfoot
45
- data-slot="table-footer"
46
- className={cn(
47
- 'bg-muted/50 border-t font-medium [&>tr]:last:border-b-0',
48
- className
49
- )}
50
- {...props}
51
- />
52
- );
53
- }
54
-
55
- function TableRow({ className, ...props }: React.ComponentProps<'tr'>) {
56
- return (
57
- <tr
58
- data-slot="table-row"
59
- className={cn(
60
- 'hover:bg-muted/50 data-[state=selected]:bg-muted border-b transition-colors',
61
- className
62
- )}
63
- {...props}
64
- />
65
- );
66
- }
67
-
68
- function TableHead({ className, ...props }: React.ComponentProps<'th'>) {
69
- return (
70
- <th
71
- data-slot="table-head"
72
- className={cn(
73
- 'text-foreground h-10 whitespace-nowrap px-2 text-left align-middle font-medium [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
74
- className
75
- )}
76
- {...props}
77
- />
78
- );
79
- }
80
-
81
- function TableCell({ className, ...props }: React.ComponentProps<'td'>) {
82
- return (
83
- <td
84
- data-slot="table-cell"
85
- className={cn(
86
- 'whitespace-nowrap p-2 align-middle [&:has([role=checkbox])]:pr-0 [&>[role=checkbox]]:translate-y-[2px]',
87
- className
88
- )}
89
- {...props}
90
- />
91
- );
92
- }
93
-
94
- function TableCaption({
95
- className,
96
- ...props
97
- }: React.ComponentProps<'caption'>) {
98
- return (
99
- <caption
100
- data-slot="table-caption"
101
- className={cn('text-muted-foreground mt-4 text-sm', className)}
102
- {...props}
103
- />
104
- );
105
- }
106
-
107
- export {
108
- Table,
109
- TableBody,
110
- TableCaption,
111
- TableCell,
112
- TableFooter,
113
- TableHead,
114
- TableHeader,
115
- TableRow,
116
- };
@@ -1,66 +0,0 @@
1
- 'use client';
2
-
3
- import * as TabsPrimitive from '@radix-ui/react-tabs';
4
- import * as React from 'react';
5
-
6
- import { cn } from './lib/utils';
7
-
8
- function Tabs({
9
- className,
10
- ...props
11
- }: React.ComponentProps<typeof TabsPrimitive.Root>) {
12
- return (
13
- <TabsPrimitive.Root
14
- data-slot="tabs"
15
- className={cn('flex flex-col gap-2', className)}
16
- {...props}
17
- />
18
- );
19
- }
20
-
21
- function TabsList({
22
- className,
23
- ...props
24
- }: React.ComponentProps<typeof TabsPrimitive.List>) {
25
- return (
26
- <TabsPrimitive.List
27
- data-slot="tabs-list"
28
- className={cn(
29
- 'bg-muted text-muted-foreground inline-flex h-9 w-fit items-center justify-center rounded-lg p-[3px]',
30
- className
31
- )}
32
- {...props}
33
- />
34
- );
35
- }
36
-
37
- function TabsTrigger({
38
- className,
39
- ...props
40
- }: React.ComponentProps<typeof TabsPrimitive.Trigger>) {
41
- return (
42
- <TabsPrimitive.Trigger
43
- data-slot="tabs-trigger"
44
- className={cn(
45
- "data-[state=active]:bg-background dark:data-[state=active]:text-foreground focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:outline-ring dark:data-[state=active]:border-input dark:data-[state=active]:bg-input/30 text-foreground dark:text-muted-foreground inline-flex h-[calc(100%-1px)] flex-1 items-center justify-center gap-1.5 whitespace-nowrap rounded-md border border-transparent px-2 py-1 text-sm font-medium transition-[color,box-shadow] focus-visible:outline-1 focus-visible:ring-[3px] disabled:pointer-events-none disabled:opacity-50 data-[state=active]:shadow-sm [&_svg:not([class*='size-'])]:size-4 [&_svg]:pointer-events-none [&_svg]:shrink-0",
46
- className
47
- )}
48
- {...props}
49
- />
50
- );
51
- }
52
-
53
- function TabsContent({
54
- className,
55
- ...props
56
- }: React.ComponentProps<typeof TabsPrimitive.Content>) {
57
- return (
58
- <TabsPrimitive.Content
59
- data-slot="tabs-content"
60
- className={cn('flex-1 outline-none', className)}
61
- {...props}
62
- />
63
- );
64
- }
65
-
66
- export { Tabs, TabsContent, TabsList, TabsTrigger };
@@ -1,18 +0,0 @@
1
- import * as React from 'react';
2
-
3
- import { cn } from './lib/utils';
4
-
5
- function Textarea({ className, ...props }: React.ComponentProps<'textarea'>) {
6
- return (
7
- <textarea
8
- data-slot="textarea"
9
- className={cn(
10
- 'border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive dark:bg-input/30 field-sizing-content shadow-xs flex min-h-16 w-full rounded-md border bg-transparent px-3 py-2 text-base outline-none transition-[color,box-shadow] focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50 md:text-sm',
11
- className
12
- )}
13
- {...props}
14
- />
15
- );
16
- }
17
-
18
- export { Textarea };
@@ -1,61 +0,0 @@
1
- 'use client';
2
-
3
- import * as TooltipPrimitive from '@radix-ui/react-tooltip';
4
- import * as React from 'react';
5
-
6
- import { cn } from './lib/utils';
7
-
8
- function TooltipProvider({
9
- delayDuration = 0,
10
- ...props
11
- }: React.ComponentProps<typeof TooltipPrimitive.Provider>) {
12
- return (
13
- <TooltipPrimitive.Provider
14
- data-slot="tooltip-provider"
15
- delayDuration={delayDuration}
16
- {...props}
17
- />
18
- );
19
- }
20
-
21
- function Tooltip({
22
- ...props
23
- }: React.ComponentProps<typeof TooltipPrimitive.Root>) {
24
- return (
25
- <TooltipProvider>
26
- <TooltipPrimitive.Root data-slot="tooltip" {...props} />
27
- </TooltipProvider>
28
- );
29
- }
30
-
31
- function TooltipTrigger({
32
- ...props
33
- }: React.ComponentProps<typeof TooltipPrimitive.Trigger>) {
34
- return <TooltipPrimitive.Trigger data-slot="tooltip-trigger" {...props} />;
35
- }
36
-
37
- function TooltipContent({
38
- className,
39
- sideOffset = 0,
40
- children,
41
- ...props
42
- }: React.ComponentProps<typeof TooltipPrimitive.Content>) {
43
- return (
44
- <TooltipPrimitive.Portal>
45
- <TooltipPrimitive.Content
46
- data-slot="tooltip-content"
47
- sideOffset={sideOffset}
48
- className={cn(
49
- 'bg-foreground text-background animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 origin-(--radix-tooltip-content-transform-origin) z-50 w-fit text-balance rounded-md px-3 py-1.5 text-xs',
50
- className
51
- )}
52
- {...props}
53
- >
54
- {children}
55
- <TooltipPrimitive.Arrow className="bg-foreground fill-foreground z-50 size-2.5 translate-y-[calc(-50%_-_2px)] rotate-45 rounded-[2px]" />
56
- </TooltipPrimitive.Content>
57
- </TooltipPrimitive.Portal>
58
- );
59
- }
60
-
61
- export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger };
@@ -1,97 +0,0 @@
1
- import { User } from 'lucide-react';
2
-
3
- import { Avatar, AvatarFallback, AvatarImage } from './avatar';
4
- import { cn } from './lib/utils';
5
-
6
- const colorClasses = [
7
- 'bg-red-500',
8
- 'bg-blue-500',
9
- 'bg-green-500',
10
- 'bg-purple-500',
11
- 'bg-orange-500',
12
- 'bg-pink-500',
13
- 'bg-cyan-500',
14
- 'bg-amber-500',
15
- 'bg-indigo-500',
16
- 'bg-emerald-500',
17
- 'bg-violet-500',
18
- 'bg-fuchsia-500',
19
- ] as const;
20
-
21
- const sizeVariants = {
22
- sm: {
23
- avatar: 'h-8 w-8',
24
- icon: 'h-4 w-4',
25
- text: 'text-xs',
26
- },
27
- md: {
28
- avatar: 'h-12 w-12',
29
- icon: 'h-6 w-6',
30
- text: 'text-sm',
31
- },
32
- lg: {
33
- avatar: 'h-16 w-16',
34
- icon: 'h-8 w-8',
35
- text: 'text-base',
36
- },
37
- xl: {
38
- avatar: 'h-20 w-20',
39
- icon: 'h-10 w-10',
40
- text: 'text-lg',
41
- },
42
- } as const;
43
-
44
- function generateColorFromString(str: string): string {
45
- const hash = str.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0);
46
- return colorClasses[hash % colorClasses.length];
47
- }
48
-
49
- function getInitials(name: string | null | undefined, email: string): string {
50
- if (name) {
51
- return name
52
- .split(' ')
53
- .map((n) => n[0])
54
- .join('')
55
- .toUpperCase()
56
- .slice(0, 2);
57
- }
58
- return email.charAt(0).toUpperCase();
59
- }
60
-
61
- interface UserAvatarProps {
62
- src?: string | null;
63
- name?: string | null;
64
- email?: string;
65
- fallback?: string;
66
- size?: keyof typeof sizeVariants;
67
- className?: string;
68
- }
69
-
70
- export function UserAvatar({
71
- src,
72
- name,
73
- email,
74
- fallback,
75
- size = 'lg',
76
- className,
77
- }: UserAvatarProps) {
78
- const displayName = name || email || 'User';
79
- const initials = fallback || (email ? getInitials(name, email) : undefined);
80
- const colorClass = email ? generateColorFromString(email) : 'bg-primary';
81
- const sizeClasses = sizeVariants[size];
82
-
83
- return (
84
- <Avatar className={cn(sizeClasses.avatar, className)}>
85
- <AvatarImage src={src ?? undefined} alt={displayName} />
86
- <AvatarFallback
87
- className={cn(
88
- colorClass,
89
- 'text-lg font-semibold text-white',
90
- sizeClasses.text
91
- )}
92
- >
93
- {initials || <User className={sizeClasses.icon} />}
94
- </AvatarFallback>
95
- </Avatar>
96
- );
97
- }
@@ -1,3 +0,0 @@
1
- export default {
2
- content: ['./src/**/*.{ts,tsx}'],
3
- };
@@ -1,12 +0,0 @@
1
- {
2
- "extends": "../../tsconfig.base.json",
3
- "compilerOptions": {
4
- "outDir": "./dist",
5
- "rootDir": "./src",
6
- "jsx": "react-jsx",
7
- "lib": ["ES2020", "dom", "dom.iterable"],
8
- "types": ["vitest/globals", "@testing-library/jest-dom"]
9
- },
10
- "include": ["src/**/*"],
11
- "exclude": ["node_modules", "dist"]
12
- }
@@ -1,18 +0,0 @@
1
- {
2
- "extends": ["//"],
3
- "tasks": {
4
- "build": {
5
- "dependsOn": ["build:components"]
6
- },
7
- "build:components": {
8
- "outputs": ["dist/**"]
9
- },
10
- "dev": {
11
- "with": ["dev:components"]
12
- },
13
- "dev:components": {
14
- "cache": false,
15
- "persistent": true
16
- }
17
- }
18
- }
@@ -1,17 +0,0 @@
1
- import react from '@vitejs/plugin-react';
2
- import path from 'path';
3
- import { defineConfig } from 'vitest/config';
4
-
5
- export default defineConfig({
6
- plugins: [react()],
7
- resolve: {
8
- alias: {
9
- '@': path.resolve(__dirname, './src'),
10
- },
11
- },
12
- test: {
13
- globals: true,
14
- environment: 'jsdom',
15
- setupFiles: ['./vitest.setup.ts'],
16
- },
17
- });
@@ -1 +0,0 @@
1
- import '@testing-library/jest-dom';
@@ -1,23 +0,0 @@
1
- {
2
- "name": "@repo/packages-utils",
3
- "version": "1.0.0",
4
- "type": "module",
5
- "exports": {
6
- "./array": "./src/array.ts",
7
- "./async": "./src/async.ts",
8
- "./date": "./src/date.ts",
9
- "./errors": "./src/errors.ts",
10
- "./number": "./src/number.ts",
11
- "./string": "./src/string.ts"
12
- },
13
- "scripts": {
14
- "typecheck": "tsc --noEmit",
15
- "lint": "eslint src",
16
- "lint:fix": "eslint src --fix",
17
- "test": "vitest run",
18
- "test:unit": "vitest run",
19
- "test:integration": "echo 'No integration tests for packages-utils'",
20
- "test:watch": "vitest",
21
- "test:coverage": "vitest run --coverage"
22
- }
23
- }