ar-saas 0.3.0 → 0.3.2

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 (114) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +338 -314
  3. package/dist/cli.js +19 -0
  4. package/dist/generator.js +166 -55
  5. package/package.json +52 -50
  6. package/templates/backend/.env.example +67 -67
  7. package/templates/backend/.prettierrc +4 -4
  8. package/templates/backend/README.md +249 -168
  9. package/templates/backend/eslint.config.mjs +35 -35
  10. package/templates/backend/nest-cli.json +8 -8
  11. package/templates/backend/package-lock.json +10979 -10979
  12. package/templates/backend/package.json +88 -88
  13. package/templates/backend/src/app.controller.spec.ts +24 -24
  14. package/templates/backend/src/app.controller.ts +15 -15
  15. package/templates/backend/src/app.module.ts +40 -40
  16. package/templates/backend/src/app.service.ts +11 -11
  17. package/templates/backend/src/common/base/base.repository.ts +221 -221
  18. package/templates/backend/src/common/base/base.schema.ts +24 -24
  19. package/templates/backend/src/common/decorators/cookie.decorator.ts +9 -9
  20. package/templates/backend/src/common/decorators/current-user.decorator.ts +20 -20
  21. package/templates/backend/src/common/decorators/workspace-id.decorator.ts +14 -14
  22. package/templates/backend/src/common/filters/global-exception.filter.ts +61 -61
  23. package/templates/backend/src/common/guards/jwt-auth.guard.ts +5 -5
  24. package/templates/backend/src/common/interceptors/workspace-tenant.interceptor.ts +45 -45
  25. package/templates/backend/src/main.ts +51 -51
  26. package/templates/backend/src/modules/auth/auth.controller.ts +158 -158
  27. package/templates/backend/src/modules/auth/auth.module.ts +20 -20
  28. package/templates/backend/src/modules/auth/auth.service.ts +257 -257
  29. package/templates/backend/src/modules/auth/dto/forgot-password.dto.ts +9 -9
  30. package/templates/backend/src/modules/auth/dto/login.dto.ts +14 -14
  31. package/templates/backend/src/modules/auth/dto/refresh-token.dto.ts +12 -12
  32. package/templates/backend/src/modules/auth/dto/register.dto.ts +26 -26
  33. package/templates/backend/src/modules/auth/dto/reset-password.dto.ts +16 -16
  34. package/templates/backend/src/modules/auth/dto/verify-email.dto.ts +9 -9
  35. package/templates/backend/src/modules/auth/strategies/jwt.strategy.ts +43 -43
  36. package/templates/backend/src/modules/mail/mail.module.ts +9 -9
  37. package/templates/backend/src/modules/mail/mail.service.ts +141 -141
  38. package/templates/backend/src/modules/users/schemas/user.schema.ts +54 -54
  39. package/templates/backend/src/modules/users/users.module.ts +14 -14
  40. package/templates/backend/src/modules/users/users.repository.ts +51 -51
  41. package/templates/backend/src/modules/users/users.service.ts +104 -104
  42. package/templates/backend/src/modules/workspaces/schemas/workspace.schema.ts +26 -26
  43. package/templates/backend/src/modules/workspaces/workspaces.module.ts +16 -16
  44. package/templates/backend/src/modules/workspaces/workspaces.repository.ts +34 -34
  45. package/templates/backend/src/modules/workspaces/workspaces.service.ts +42 -42
  46. package/templates/backend/test/app.e2e-spec.ts +25 -25
  47. package/templates/backend/test/jest-e2e.json +9 -9
  48. package/templates/backend/tsconfig.build.json +4 -4
  49. package/templates/backend/tsconfig.json +26 -26
  50. package/templates/frontend/.env.local.example +1 -1
  51. package/templates/frontend/README.md +152 -0
  52. package/templates/frontend/components.json +20 -20
  53. package/templates/frontend/eslint.config.mjs +14 -14
  54. package/templates/frontend/next.config.ts +5 -5
  55. package/templates/frontend/package-lock.json +6722 -6722
  56. package/templates/frontend/package.json +48 -48
  57. package/templates/frontend/pnpm-lock.yaml +5012 -5012
  58. package/templates/frontend/pnpm-workspace.yaml +3 -3
  59. package/templates/frontend/postcss.config.mjs +7 -7
  60. package/templates/frontend/src/app/(auth)/forgot-password/page.tsx +84 -84
  61. package/templates/frontend/src/app/(auth)/layout.tsx +28 -28
  62. package/templates/frontend/src/app/(auth)/login/page.tsx +111 -111
  63. package/templates/frontend/src/app/(auth)/register/page.tsx +161 -161
  64. package/templates/frontend/src/app/(auth)/reset-password/page.tsx +120 -120
  65. package/templates/frontend/src/app/(auth)/verify-email/page.tsx +78 -78
  66. package/templates/frontend/src/app/(dashboard)/billing/page.tsx +111 -111
  67. package/templates/frontend/src/app/(dashboard)/dashboard/page.tsx +105 -105
  68. package/templates/frontend/src/app/(dashboard)/layout.tsx +38 -38
  69. package/templates/frontend/src/app/(dashboard)/profile/page.tsx +226 -226
  70. package/templates/frontend/src/app/(dashboard)/settings/page.tsx +156 -156
  71. package/templates/frontend/src/app/(dashboard)/team/page.tsx +178 -178
  72. package/templates/frontend/src/app/(legal)/privacy/page.tsx +127 -127
  73. package/templates/frontend/src/app/(legal)/terms/page.tsx +118 -118
  74. package/templates/frontend/src/app/globals.css +81 -81
  75. package/templates/frontend/src/app/layout.tsx +26 -26
  76. package/templates/frontend/src/app/page.tsx +5 -45
  77. package/templates/frontend/src/app/setup/page.tsx +371 -275
  78. package/templates/frontend/src/components/dashboard/header.tsx +89 -89
  79. package/templates/frontend/src/components/dashboard/sidebar.tsx +71 -71
  80. package/templates/frontend/src/components/dashboard/stat-card.tsx +34 -34
  81. package/templates/frontend/src/components/landing/faq.tsx +39 -39
  82. package/templates/frontend/src/components/landing/features.tsx +54 -54
  83. package/templates/frontend/src/components/landing/footer.tsx +76 -76
  84. package/templates/frontend/src/components/landing/hero.tsx +72 -72
  85. package/templates/frontend/src/components/landing/navbar.tsx +78 -78
  86. package/templates/frontend/src/components/landing/pricing.tsx +90 -90
  87. package/templates/frontend/src/components/ui/accordion.tsx +52 -52
  88. package/templates/frontend/src/components/ui/avatar.tsx +46 -46
  89. package/templates/frontend/src/components/ui/badge.tsx +30 -30
  90. package/templates/frontend/src/components/ui/button.tsx +52 -52
  91. package/templates/frontend/src/components/ui/card.tsx +50 -50
  92. package/templates/frontend/src/components/ui/checkbox.tsx +27 -27
  93. package/templates/frontend/src/components/ui/dialog.tsx +100 -100
  94. package/templates/frontend/src/components/ui/dropdown-menu.tsx +173 -173
  95. package/templates/frontend/src/components/ui/form.tsx +158 -158
  96. package/templates/frontend/src/components/ui/input.tsx +21 -21
  97. package/templates/frontend/src/components/ui/label.tsx +22 -22
  98. package/templates/frontend/src/components/ui/separator.tsx +25 -25
  99. package/templates/frontend/src/components/ui/skeleton.tsx +7 -7
  100. package/templates/frontend/src/components/ui/switch.tsx +28 -28
  101. package/templates/frontend/src/components/ui/tabs.tsx +54 -54
  102. package/templates/frontend/src/components/ui/textarea.tsx +20 -20
  103. package/templates/frontend/src/components/ui/toast.tsx +109 -109
  104. package/templates/frontend/src/components/ui/toaster.tsx +30 -30
  105. package/templates/frontend/src/config/site.ts +197 -197
  106. package/templates/frontend/src/hooks/use-toast.ts +116 -116
  107. package/templates/frontend/src/lib/api/auth.ts +39 -39
  108. package/templates/frontend/src/lib/api/client.ts +66 -66
  109. package/templates/frontend/src/lib/hooks/use-auth.ts +1 -1
  110. package/templates/frontend/src/lib/utils.ts +6 -6
  111. package/templates/frontend/src/providers/auth-provider.tsx +60 -60
  112. package/templates/frontend/src/types/api.ts +12 -12
  113. package/templates/frontend/src/types/auth.ts +27 -27
  114. package/templates/frontend/tsconfig.json +23 -23
@@ -1,20 +1,20 @@
1
- import * as React from 'react'
2
- import { cn } from '@/lib/utils'
3
-
4
- const Textarea = React.forwardRef<HTMLTextAreaElement, React.ComponentProps<'textarea'>>(
5
- ({ className, ...props }, ref) => {
6
- return (
7
- <textarea
8
- className={cn(
9
- 'flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
10
- className,
11
- )}
12
- ref={ref}
13
- {...props}
14
- />
15
- )
16
- },
17
- )
18
- Textarea.displayName = 'Textarea'
19
-
20
- export { Textarea }
1
+ import * as React from 'react'
2
+ import { cn } from '@/lib/utils'
3
+
4
+ const Textarea = React.forwardRef<HTMLTextAreaElement, React.ComponentProps<'textarea'>>(
5
+ ({ className, ...props }, ref) => {
6
+ return (
7
+ <textarea
8
+ className={cn(
9
+ 'flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50',
10
+ className,
11
+ )}
12
+ ref={ref}
13
+ {...props}
14
+ />
15
+ )
16
+ },
17
+ )
18
+ Textarea.displayName = 'Textarea'
19
+
20
+ export { Textarea }
@@ -1,109 +1,109 @@
1
- 'use client'
2
-
3
- import * as React from 'react'
4
- import * as ToastPrimitive from '@radix-ui/react-toast'
5
- import { cva, type VariantProps } from 'class-variance-authority'
6
- import { X } from 'lucide-react'
7
- import { cn } from '@/lib/utils'
8
-
9
- const ToastProvider = ToastPrimitive.Provider
10
-
11
- const ToastViewport = React.forwardRef<
12
- React.ElementRef<typeof ToastPrimitive.Viewport>,
13
- React.ComponentPropsWithoutRef<typeof ToastPrimitive.Viewport>
14
- >(({ className, ...props }, ref) => (
15
- <ToastPrimitive.Viewport
16
- ref={ref}
17
- className={cn(
18
- 'fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]',
19
- className,
20
- )}
21
- {...props}
22
- />
23
- ))
24
- ToastViewport.displayName = ToastPrimitive.Viewport.displayName
25
-
26
- const toastVariants = cva(
27
- 'group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',
28
- {
29
- variants: {
30
- variant: {
31
- default: 'border bg-background text-foreground',
32
- destructive: 'destructive group border-destructive bg-destructive text-destructive-foreground',
33
- },
34
- },
35
- defaultVariants: { variant: 'default' },
36
- },
37
- )
38
-
39
- const Toast = React.forwardRef<
40
- React.ElementRef<typeof ToastPrimitive.Root>,
41
- React.ComponentPropsWithoutRef<typeof ToastPrimitive.Root> & VariantProps<typeof toastVariants>
42
- >(({ className, variant, ...props }, ref) => (
43
- <ToastPrimitive.Root ref={ref} className={cn(toastVariants({ variant }), className)} {...props} />
44
- ))
45
- Toast.displayName = ToastPrimitive.Root.displayName
46
-
47
- const ToastAction = React.forwardRef<
48
- React.ElementRef<typeof ToastPrimitive.Action>,
49
- React.ComponentPropsWithoutRef<typeof ToastPrimitive.Action>
50
- >(({ className, ...props }, ref) => (
51
- <ToastPrimitive.Action
52
- ref={ref}
53
- className={cn(
54
- 'inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive',
55
- className,
56
- )}
57
- {...props}
58
- />
59
- ))
60
- ToastAction.displayName = ToastPrimitive.Action.displayName
61
-
62
- const ToastClose = React.forwardRef<
63
- React.ElementRef<typeof ToastPrimitive.Close>,
64
- React.ComponentPropsWithoutRef<typeof ToastPrimitive.Close>
65
- >(({ className, ...props }, ref) => (
66
- <ToastPrimitive.Close
67
- ref={ref}
68
- className={cn(
69
- 'absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600',
70
- className,
71
- )}
72
- toast-close=""
73
- {...props}
74
- >
75
- <X className="h-4 w-4" />
76
- </ToastPrimitive.Close>
77
- ))
78
- ToastClose.displayName = ToastPrimitive.Close.displayName
79
-
80
- const ToastTitle = React.forwardRef<
81
- React.ElementRef<typeof ToastPrimitive.Title>,
82
- React.ComponentPropsWithoutRef<typeof ToastPrimitive.Title>
83
- >(({ className, ...props }, ref) => (
84
- <ToastPrimitive.Title ref={ref} className={cn('text-sm font-semibold [&+div]:text-xs', className)} {...props} />
85
- ))
86
- ToastTitle.displayName = ToastPrimitive.Title.displayName
87
-
88
- const ToastDescription = React.forwardRef<
89
- React.ElementRef<typeof ToastPrimitive.Description>,
90
- React.ComponentPropsWithoutRef<typeof ToastPrimitive.Description>
91
- >(({ className, ...props }, ref) => (
92
- <ToastPrimitive.Description ref={ref} className={cn('text-sm opacity-90', className)} {...props} />
93
- ))
94
- ToastDescription.displayName = ToastPrimitive.Description.displayName
95
-
96
- type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>
97
- type ToastActionElement = React.ReactElement<typeof ToastAction>
98
-
99
- export {
100
- type ToastProps,
101
- type ToastActionElement,
102
- ToastProvider,
103
- ToastViewport,
104
- Toast,
105
- ToastTitle,
106
- ToastDescription,
107
- ToastClose,
108
- ToastAction,
109
- }
1
+ 'use client'
2
+
3
+ import * as React from 'react'
4
+ import * as ToastPrimitive from '@radix-ui/react-toast'
5
+ import { cva, type VariantProps } from 'class-variance-authority'
6
+ import { X } from 'lucide-react'
7
+ import { cn } from '@/lib/utils'
8
+
9
+ const ToastProvider = ToastPrimitive.Provider
10
+
11
+ const ToastViewport = React.forwardRef<
12
+ React.ElementRef<typeof ToastPrimitive.Viewport>,
13
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Viewport>
14
+ >(({ className, ...props }, ref) => (
15
+ <ToastPrimitive.Viewport
16
+ ref={ref}
17
+ className={cn(
18
+ 'fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]',
19
+ className,
20
+ )}
21
+ {...props}
22
+ />
23
+ ))
24
+ ToastViewport.displayName = ToastPrimitive.Viewport.displayName
25
+
26
+ const toastVariants = cva(
27
+ 'group pointer-events-auto relative flex w-full items-center justify-between space-x-2 overflow-hidden rounded-md border p-4 pr-6 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full',
28
+ {
29
+ variants: {
30
+ variant: {
31
+ default: 'border bg-background text-foreground',
32
+ destructive: 'destructive group border-destructive bg-destructive text-destructive-foreground',
33
+ },
34
+ },
35
+ defaultVariants: { variant: 'default' },
36
+ },
37
+ )
38
+
39
+ const Toast = React.forwardRef<
40
+ React.ElementRef<typeof ToastPrimitive.Root>,
41
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Root> & VariantProps<typeof toastVariants>
42
+ >(({ className, variant, ...props }, ref) => (
43
+ <ToastPrimitive.Root ref={ref} className={cn(toastVariants({ variant }), className)} {...props} />
44
+ ))
45
+ Toast.displayName = ToastPrimitive.Root.displayName
46
+
47
+ const ToastAction = React.forwardRef<
48
+ React.ElementRef<typeof ToastPrimitive.Action>,
49
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Action>
50
+ >(({ className, ...props }, ref) => (
51
+ <ToastPrimitive.Action
52
+ ref={ref}
53
+ className={cn(
54
+ 'inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium transition-colors hover:bg-secondary focus:outline-none focus:ring-1 focus:ring-ring disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive',
55
+ className,
56
+ )}
57
+ {...props}
58
+ />
59
+ ))
60
+ ToastAction.displayName = ToastPrimitive.Action.displayName
61
+
62
+ const ToastClose = React.forwardRef<
63
+ React.ElementRef<typeof ToastPrimitive.Close>,
64
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Close>
65
+ >(({ className, ...props }, ref) => (
66
+ <ToastPrimitive.Close
67
+ ref={ref}
68
+ className={cn(
69
+ 'absolute right-1 top-1 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-1 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600',
70
+ className,
71
+ )}
72
+ toast-close=""
73
+ {...props}
74
+ >
75
+ <X className="h-4 w-4" />
76
+ </ToastPrimitive.Close>
77
+ ))
78
+ ToastClose.displayName = ToastPrimitive.Close.displayName
79
+
80
+ const ToastTitle = React.forwardRef<
81
+ React.ElementRef<typeof ToastPrimitive.Title>,
82
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Title>
83
+ >(({ className, ...props }, ref) => (
84
+ <ToastPrimitive.Title ref={ref} className={cn('text-sm font-semibold [&+div]:text-xs', className)} {...props} />
85
+ ))
86
+ ToastTitle.displayName = ToastPrimitive.Title.displayName
87
+
88
+ const ToastDescription = React.forwardRef<
89
+ React.ElementRef<typeof ToastPrimitive.Description>,
90
+ React.ComponentPropsWithoutRef<typeof ToastPrimitive.Description>
91
+ >(({ className, ...props }, ref) => (
92
+ <ToastPrimitive.Description ref={ref} className={cn('text-sm opacity-90', className)} {...props} />
93
+ ))
94
+ ToastDescription.displayName = ToastPrimitive.Description.displayName
95
+
96
+ type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>
97
+ type ToastActionElement = React.ReactElement<typeof ToastAction>
98
+
99
+ export {
100
+ type ToastProps,
101
+ type ToastActionElement,
102
+ ToastProvider,
103
+ ToastViewport,
104
+ Toast,
105
+ ToastTitle,
106
+ ToastDescription,
107
+ ToastClose,
108
+ ToastAction,
109
+ }
@@ -1,30 +1,30 @@
1
- 'use client'
2
-
3
- import { useToast } from '@/hooks/use-toast'
4
- import {
5
- Toast,
6
- ToastClose,
7
- ToastDescription,
8
- ToastProvider,
9
- ToastTitle,
10
- ToastViewport,
11
- } from '@/components/ui/toast'
12
-
13
- export function Toaster() {
14
- const { toasts } = useToast()
15
- return (
16
- <ToastProvider>
17
- {toasts.map(({ id, title, description, action, ...props }) => (
18
- <Toast key={id} {...props}>
19
- <div className="grid gap-1">
20
- {title && <ToastTitle>{title}</ToastTitle>}
21
- {description && <ToastDescription>{description}</ToastDescription>}
22
- </div>
23
- {action}
24
- <ToastClose />
25
- </Toast>
26
- ))}
27
- <ToastViewport />
28
- </ToastProvider>
29
- )
30
- }
1
+ 'use client'
2
+
3
+ import { useToast } from '@/hooks/use-toast'
4
+ import {
5
+ Toast,
6
+ ToastClose,
7
+ ToastDescription,
8
+ ToastProvider,
9
+ ToastTitle,
10
+ ToastViewport,
11
+ } from '@/components/ui/toast'
12
+
13
+ export function Toaster() {
14
+ const { toasts } = useToast()
15
+ return (
16
+ <ToastProvider>
17
+ {toasts.map(({ id, title, description, action, ...props }) => (
18
+ <Toast key={id} {...props}>
19
+ <div className="grid gap-1">
20
+ {title && <ToastTitle>{title}</ToastTitle>}
21
+ {description && <ToastDescription>{description}</ToastDescription>}
22
+ </div>
23
+ {action}
24
+ <ToastClose />
25
+ </Toast>
26
+ ))}
27
+ <ToastViewport />
28
+ </ToastProvider>
29
+ )
30
+ }