create-ej-app 3.2.0 → 5.0.0
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.
- package/LICENSE +1 -1
- package/cli.js +5 -1
- package/cli.ts +40 -33
- package/package.json +4 -4
- package/template/base/.env.example +10 -9
- package/template/base/.eslintrc.cjs +17 -15
- package/template/base/components.json +1 -1
- package/template/base/drizzle.config.ts +11 -0
- package/template/base/next.config.mjs +1 -12
- package/template/base/package.json +63 -56
- package/template/base/postcss.config.mjs +8 -0
- package/template/base/prettier.config.mjs +11 -0
- package/template/base/public/vercel.svg +1 -0
- package/template/base/src/app/(app)/dashboard/layout.tsx +14 -0
- package/template/base/src/app/(app)/dashboard/page.tsx +0 -7
- package/template/base/src/app/(app)/layout.tsx +55 -20
- package/template/base/src/app/(app)/roles/[id]/actions.ts +59 -0
- package/template/base/src/app/(app)/roles/[id]/page.tsx +46 -0
- package/template/base/src/app/(app)/roles/[id]/render.tsx +264 -0
- package/template/base/src/app/(app)/roles/[id]/validation.ts +22 -0
- package/template/base/src/app/(app)/roles/actions.ts +33 -0
- package/template/base/src/app/(app)/roles/page.tsx +52 -0
- package/template/base/src/app/(app)/roles/render.tsx +80 -0
- package/template/base/src/app/(app)/settings/actions.ts +11 -12
- package/template/base/src/app/(app)/settings/layout.tsx +14 -0
- package/template/base/src/app/(app)/settings/page.tsx +1 -10
- package/template/base/src/app/(app)/settings/render.tsx +11 -17
- package/template/base/src/app/(app)/settings/validation.ts +5 -0
- package/template/base/src/app/(app)/tasks/[id]/actions.ts +69 -124
- package/template/base/src/app/(app)/tasks/[id]/page.tsx +37 -3
- package/template/base/src/app/(app)/tasks/[id]/render.tsx +162 -93
- package/template/base/src/app/(app)/tasks/[id]/validation.ts +18 -0
- package/template/base/src/app/(app)/tasks/actions.ts +34 -64
- package/template/base/src/app/(app)/tasks/page.tsx +15 -9
- package/template/base/src/app/(app)/tasks/render.tsx +28 -6
- package/template/base/src/app/(app)/tasks/statusEnum.ts +3 -0
- package/template/base/src/app/(app)/users/[id]/actions.ts +47 -62
- package/template/base/src/app/(app)/users/[id]/page.tsx +15 -8
- package/template/base/src/app/(app)/users/[id]/render.tsx +119 -34
- package/template/base/src/app/(app)/users/[id]/validation.ts +18 -0
- package/template/base/src/app/(app)/users/actions.ts +28 -49
- package/template/base/src/app/(app)/users/page.tsx +22 -9
- package/template/base/src/app/(app)/users/render.tsx +47 -3
- package/template/base/src/app/(auth)/layout.tsx +7 -0
- package/template/base/src/app/(auth)/login/page.tsx +2 -2
- package/template/base/src/app/(auth)/login/render.tsx +146 -0
- package/template/base/src/app/(marketing)/layout.tsx +1 -1
- package/template/base/src/app/(marketing)/page.tsx +8 -7
- package/template/base/src/app/favicon.ico +0 -0
- package/template/base/src/app/layout.tsx +14 -17
- package/template/base/src/components/app-nav-command.tsx +18 -0
- package/template/base/src/components/data-table/data-table-column-header.tsx +2 -2
- package/template/base/src/components/icons.tsx +21 -5
- package/template/base/src/components/ui/alert-dialog.tsx +1 -1
- package/template/base/src/components/ui/command.tsx +1 -1
- package/template/base/src/components/ui/dialog.tsx +1 -1
- package/template/base/src/components/ui/sonner.tsx +31 -0
- package/template/base/src/components/user-avatar.tsx +4 -2
- package/template/base/src/data-access/resource.ts +85 -0
- package/template/base/src/data-access/role-permission.ts +45 -0
- package/template/base/src/data-access/role.ts +105 -0
- package/template/base/src/data-access/task.ts +141 -0
- package/template/base/src/data-access/user.ts +141 -0
- package/template/base/src/db/index.ts +14 -0
- package/template/base/src/db/schema.ts +287 -0
- package/template/base/src/env.mjs +10 -30
- package/template/base/src/hooks/use-lock-body.tsx +2 -1
- package/template/base/src/lib/auth.ts +32 -23
- package/template/base/src/lib/currentUser.ts +8 -0
- package/template/base/src/lib/s3Client.ts +156 -0
- package/template/base/src/lib/safe-action.ts +19 -0
- package/template/base/src/lib/sortOrderEnum.ts +2 -0
- package/template/base/src/use-case/role-permission.ts +19 -0
- package/template/base/src/use-case/role.ts +110 -0
- package/template/base/src/use-case/task.ts +166 -0
- package/template/base/src/use-case/user.ts +121 -0
- package/template/base/tailwind.config.ts +5 -4
- package/template/base/tsconfig.json +3 -2
- package/template/new/.env.example +13 -0
- package/template/new/components.json +22 -0
- package/template/new/drizzle.config.ts +10 -0
- package/template/new/eslint.config.mjs +18 -0
- package/template/new/next.config.ts +14 -0
- package/template/new/package.json +81 -0
- package/template/new/postcss.config.mjs +5 -0
- package/template/new/prettier.config.mjs +11 -0
- package/template/new/public/placeholder.svg +1 -0
- package/template/new/src/app/(auth)/login/email-login-form.tsx +97 -0
- package/template/new/src/app/(auth)/login/page.tsx +72 -0
- package/template/new/src/app/(auth)/login/social-login-buttons.tsx +69 -0
- package/template/new/src/app/api/auth/[...all]/route.ts +4 -0
- package/template/new/src/app/favicon.ico +0 -0
- package/template/new/src/app/globals.css +128 -0
- package/template/new/src/app/layout.tsx +50 -0
- package/template/new/src/app/page.tsx +3 -0
- package/template/new/src/components/loader.tsx +25 -0
- package/template/new/src/components/react-query-provider.tsx +12 -0
- package/template/new/src/components/screen-size.tsx +40 -0
- package/template/new/src/components/theme-toggle.tsx +22 -0
- package/template/new/src/components/ui/button.tsx +60 -0
- package/template/new/src/components/ui/card.tsx +92 -0
- package/template/new/src/components/ui/form.tsx +167 -0
- package/template/new/src/components/ui/input.tsx +21 -0
- package/template/new/src/components/ui/label.tsx +24 -0
- package/template/new/src/components/ui/separator.tsx +28 -0
- package/template/new/src/components/ui/sonner.tsx +40 -0
- package/template/new/src/db/index.ts +7 -0
- package/template/new/src/db/schema.ts +74 -0
- package/template/new/src/env.ts +42 -0
- package/template/new/src/lib/auth-client.ts +18 -0
- package/template/new/src/lib/auth.ts +67 -0
- package/template/new/src/lib/safe-action.ts +15 -0
- package/template/new/src/lib/toast-message.ts +15 -0
- package/template/new/tsconfig.json +49 -0
- package/template/prisma/.env.example +16 -0
- package/template/prisma/.eslintrc.cjs +24 -0
- package/template/prisma/components.json +17 -0
- package/template/prisma/next.config.mjs +15 -0
- package/template/prisma/package.json +80 -0
- package/template/prisma/public/next.svg +1 -0
- package/template/prisma/src/app/(app)/dashboard/page.tsx +19 -0
- package/template/prisma/src/app/(app)/layout.tsx +90 -0
- package/template/prisma/src/app/(app)/settings/actions.ts +18 -0
- package/template/prisma/src/app/(app)/settings/loading.tsx +28 -0
- package/template/prisma/src/app/(app)/settings/page.tsx +28 -0
- package/template/prisma/src/app/(app)/settings/render.tsx +113 -0
- package/template/prisma/src/app/(app)/tasks/[id]/actions.ts +147 -0
- package/template/prisma/src/app/(app)/tasks/[id]/page.tsx +25 -0
- package/template/prisma/src/app/(app)/tasks/[id]/render.tsx +413 -0
- package/template/prisma/src/app/(app)/tasks/actions.ts +69 -0
- package/template/prisma/src/app/(app)/tasks/page.tsx +53 -0
- package/template/prisma/src/app/(app)/tasks/render.tsx +107 -0
- package/template/prisma/src/app/(app)/users/[id]/actions.ts +83 -0
- package/template/prisma/src/app/(app)/users/[id]/page.tsx +32 -0
- package/template/prisma/src/app/(app)/users/[id]/render.tsx +240 -0
- package/template/prisma/src/app/(app)/users/actions.ts +55 -0
- package/template/prisma/src/app/(app)/users/page.tsx +49 -0
- package/template/prisma/src/app/(app)/users/render.tsx +80 -0
- package/template/prisma/src/app/(auth)/layout.tsx +20 -0
- package/template/prisma/src/app/(auth)/login/page.tsx +49 -0
- package/template/prisma/src/app/(marketing)/layout.tsx +42 -0
- package/template/prisma/src/app/(marketing)/page.tsx +96 -0
- package/template/prisma/src/app/api/auth/[...nextauth]/route.ts +7 -0
- package/template/prisma/src/app/favicon.ico +0 -0
- package/template/prisma/src/app/layout.tsx +34 -0
- package/template/prisma/src/components/app-nav-command.tsx +160 -0
- package/template/prisma/src/components/dark-mode-toggle.tsx +43 -0
- package/template/prisma/src/components/data-table/data-table-column-header.tsx +91 -0
- package/template/prisma/src/components/data-table/data-table-faceted-filter.tsx +149 -0
- package/template/prisma/src/components/data-table/data-table-loading.tsx +77 -0
- package/template/prisma/src/components/data-table/data-table-pagination.tsx +94 -0
- package/template/prisma/src/components/data-table/data-table-toolbar.tsx +78 -0
- package/template/prisma/src/components/data-table/data-table-types.ts +17 -0
- package/template/prisma/src/components/data-table/data-table-view-options.tsx +59 -0
- package/template/prisma/src/components/data-table/data-table.tsx +301 -0
- package/template/prisma/src/components/data-table/simple-data-table.tsx +109 -0
- package/template/prisma/src/components/empty-placeholder.tsx +78 -0
- package/template/prisma/src/components/heading.tsx +17 -0
- package/template/prisma/src/components/icons.tsx +85 -0
- package/template/prisma/src/components/main-nav.tsx +64 -0
- package/template/prisma/src/components/shell.tsx +13 -0
- package/template/prisma/src/components/side-nav.tsx +51 -0
- package/template/prisma/src/components/site-footer.tsx +31 -0
- package/template/prisma/src/components/system-info.tsx +36 -0
- package/template/prisma/src/components/ui/alert-dialog.tsx +141 -0
- package/template/prisma/src/components/ui/avatar.tsx +50 -0
- package/template/prisma/src/components/ui/badge.tsx +36 -0
- package/template/prisma/src/components/ui/button.tsx +56 -0
- package/template/prisma/src/components/ui/card.tsx +79 -0
- package/template/prisma/src/components/ui/checkbox.tsx +30 -0
- package/template/prisma/src/components/ui/command.tsx +155 -0
- package/template/prisma/src/components/ui/dialog.tsx +122 -0
- package/template/prisma/src/components/ui/dropdown-menu.tsx +200 -0
- package/template/prisma/src/components/ui/form.tsx +176 -0
- package/template/prisma/src/components/ui/input.tsx +25 -0
- package/template/prisma/src/components/ui/label.tsx +26 -0
- package/template/prisma/src/components/ui/popover.tsx +31 -0
- package/template/prisma/src/components/ui/select.tsx +160 -0
- package/template/prisma/src/components/ui/separator.tsx +31 -0
- package/template/prisma/src/components/ui/skeleton.tsx +15 -0
- package/template/prisma/src/components/ui/table.tsx +117 -0
- package/template/prisma/src/components/user-account-nav.tsx +60 -0
- package/template/prisma/src/components/user-avatar.tsx +25 -0
- package/template/prisma/src/env.mjs +78 -0
- package/template/prisma/src/hooks/use-debounce.ts +17 -0
- package/template/prisma/src/hooks/use-lock-body.tsx +12 -0
- package/template/prisma/src/lib/auth.ts +80 -0
- package/template/prisma/src/lib/cn.ts +4 -0
- package/template/prisma/src/lib/delay.ts +2 -0
- package/template/prisma/src/lib/formatDate.ts +11 -0
- package/template/prisma/src/lib/generateLabel.ts +5 -0
- package/template/prisma/src/lib/siteConfig.ts +4 -0
- package/template/prisma/src/styles/globals.css +76 -0
- package/template/prisma/tailwind.config.ts +80 -0
- package/template/prisma/tsconfig.json +46 -0
- package/template/prisma-advanced/src/lib/cn.ts +4 -0
- package/template/prisma-advanced/src/lib/delay.ts +2 -0
- package/template/prisma-advanced/src/lib/siteConfig.ts +4 -0
- /package/template/{advanced/src/styles → base/src/app}/globals.css +0 -0
- /package/template/{advanced/src/hooks/use-debounce.ts → base/src/hooks/use-debounce.tsx} +0 -0
- /package/template/{advanced → new}/src/lib/cn.ts +0 -0
- /package/template/{advanced → new}/src/lib/delay.ts +0 -0
- /package/template/{advanced → new}/src/lib/siteConfig.ts +0 -0
- /package/template/{base → prisma}/postcss.config.cjs +0 -0
- /package/template/{base → prisma}/prettier.config.ts +0 -0
- /package/template/{base → prisma}/prisma/schema.prisma +0 -0
- /package/template/{base → prisma}/src/app/(auth)/login/user-auth-form.tsx +0 -0
- /package/template/{base → prisma}/src/app/api/upload/route.ts +0 -0
- /package/template/{advanced → prisma}/src/components/mobile-nav.tsx +0 -0
- /package/template/{base → prisma}/src/components/theme-provider.tsx +0 -0
- /package/template/{base → prisma}/src/components/ui/textarea.tsx +0 -0
- /package/template/{base → prisma}/src/components/ui/toast.tsx +0 -0
- /package/template/{base → prisma}/src/components/ui/toaster.tsx +0 -0
- /package/template/{base → prisma}/src/components/ui/use-toast.ts +0 -0
- /package/template/{base → prisma}/src/lib/db.ts +0 -0
- /package/template/{base → prisma}/src/lib/storageClient.ts +0 -0
- /package/template/{base → prisma}/src/styles/editor.css +0 -0
- /package/template/{base → prisma}/src/types/UnwrapPromise.ts +0 -0
- /package/template/{advanced → prisma-advanced}/.env.example +0 -0
- /package/template/{advanced → prisma-advanced}/.eslintrc.cjs +0 -0
- /package/template/{advanced → prisma-advanced}/components.json +0 -0
- /package/template/{advanced → prisma-advanced}/next.config.mjs +0 -0
- /package/template/{advanced → prisma-advanced}/package.json +0 -0
- /package/template/{advanced → prisma-advanced}/postcss.config.cjs +0 -0
- /package/template/{advanced → prisma-advanced}/prettier.config.ts +0 -0
- /package/template/{advanced → prisma-advanced}/prisma/schema.prisma +0 -0
- /package/template/{advanced → prisma-advanced}/public/next.svg +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/dashboard/page.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/layout.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/roles/[id]/actions.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/roles/[id]/page.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/roles/[id]/render.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/roles/actions.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/roles/page.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/roles/render.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/settings/actions.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/settings/loading.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/settings/page.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/settings/render.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/tasks/[id]/actions.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/tasks/[id]/page.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/tasks/[id]/render.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/tasks/actions.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/tasks/page.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/tasks/render.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/users/[id]/actions.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/users/[id]/page.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/users/[id]/render.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/users/actions.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/users/page.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(app)/users/render.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(auth)/layout.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(auth)/login/page.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(auth)/login/user-auth-form.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(marketing)/layout.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/(marketing)/page.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/api/auth/[...nextauth]/route.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/api/upload/route.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/favicon.ico +0 -0
- /package/template/{advanced → prisma-advanced}/src/app/layout.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/app-nav-command.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/dark-mode-toggle.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/data-table/data-table-column-header.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/data-table/data-table-faceted-filter.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/data-table/data-table-loading.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/data-table/data-table-pagination.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/data-table/data-table-toolbar.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/data-table/data-table-types.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/data-table/data-table-view-options.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/data-table/data-table.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/data-table/simple-data-table.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/empty-placeholder.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/heading.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/icons.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/main-nav.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/shell.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/side-nav.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/site-footer.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/system-info.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/theme-provider.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/alert-dialog.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/avatar.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/badge.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/button.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/card.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/checkbox.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/command.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/dialog.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/dropdown-menu.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/form.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/input.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/label.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/popover.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/select.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/separator.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/skeleton.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/table.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/textarea.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/toast.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/toaster.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/ui/use-toast.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/user-account-nav.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/components/user-avatar.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/env.mjs +0 -0
- /package/template/{base → prisma-advanced}/src/hooks/use-debounce.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/hooks/use-lock-body.tsx +0 -0
- /package/template/{advanced → prisma-advanced}/src/lib/auth.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/lib/db.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/lib/formatDate.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/lib/generateLabel.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/lib/storageClient.ts +0 -0
- /package/template/{advanced → prisma-advanced}/src/styles/editor.css +0 -0
- /package/template/{base → prisma-advanced}/src/styles/globals.css +0 -0
- /package/template/{advanced → prisma-advanced}/src/types/UnwrapPromise.ts +0 -0
- /package/template/{advanced → prisma-advanced}/tailwind.config.ts +0 -0
- /package/template/{advanced → prisma-advanced}/tsconfig.json +0 -0
package/LICENSE
CHANGED
package/cli.js
CHANGED
|
@@ -40,10 +40,14 @@ commander_1.program.action(() => __awaiter(void 0, void 0, void 0, function* ()
|
|
|
40
40
|
choices: [
|
|
41
41
|
{
|
|
42
42
|
name: 'base',
|
|
43
|
+
message: 'Base setup with ts, shadcn, auth, drizzle, User Types and ACLs (roles & permissions)'
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
name: 'prisma',
|
|
43
47
|
message: 'Base setup with ts, shadcn, prisma, auth, editor.js'
|
|
44
48
|
},
|
|
45
49
|
{
|
|
46
|
-
name: 'advanced',
|
|
50
|
+
name: 'prisma-advanced',
|
|
47
51
|
message: 'Advanced setup with User Types and ACLs (roles & permissions)'
|
|
48
52
|
}
|
|
49
53
|
]
|
package/cli.ts
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
import { program } from 'commander'
|
|
4
|
-
import { prompt } from 'enquirer'
|
|
5
|
-
import fs from 'fs'
|
|
6
|
-
import path from 'path'
|
|
3
|
+
import { program } from 'commander'
|
|
4
|
+
import { prompt } from 'enquirer'
|
|
5
|
+
import fs from 'fs'
|
|
6
|
+
import path from 'path'
|
|
7
7
|
//@ts-ignore
|
|
8
|
-
import copydir from 'copy-dir'
|
|
8
|
+
import copydir from 'copy-dir'
|
|
9
9
|
|
|
10
10
|
interface Response {
|
|
11
|
-
projectName: string
|
|
12
|
-
description: string
|
|
13
|
-
template: string
|
|
11
|
+
projectName: string
|
|
12
|
+
description: string
|
|
13
|
+
template: string
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
program.action(async () => {
|
|
@@ -34,48 +34,55 @@ program.action(async () => {
|
|
|
34
34
|
choices: [
|
|
35
35
|
{
|
|
36
36
|
name: 'base',
|
|
37
|
+
message:
|
|
38
|
+
'Base setup with ts, shadcn, auth, drizzle, User Types and ACLs (roles & permissions)'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'prisma',
|
|
37
42
|
message: 'Base setup with ts, shadcn, prisma, auth, editor.js'
|
|
38
43
|
},
|
|
39
44
|
{
|
|
40
|
-
name: 'advanced',
|
|
45
|
+
name: 'prisma-advanced',
|
|
41
46
|
message:
|
|
42
47
|
'Advanced setup with User Types and ACLs (roles & permissions)'
|
|
43
48
|
}
|
|
44
49
|
]
|
|
45
50
|
}
|
|
46
|
-
])
|
|
51
|
+
])
|
|
47
52
|
|
|
48
|
-
const { projectName, description, template } = response
|
|
53
|
+
const { projectName, description, template } = response
|
|
49
54
|
|
|
50
|
-
const projectDir = path.join(process.cwd(), projectName)
|
|
55
|
+
const projectDir = path.join(process.cwd(), projectName)
|
|
51
56
|
|
|
52
57
|
if (fs.existsSync(projectDir)) {
|
|
53
|
-
console.error(`Error: Directory '${projectName}' already exists.`)
|
|
54
|
-
process.exit(1)
|
|
58
|
+
console.error(`Error: Directory '${projectName}' already exists.`)
|
|
59
|
+
process.exit(1)
|
|
55
60
|
}
|
|
56
61
|
|
|
57
|
-
fs.mkdirSync(projectDir)
|
|
62
|
+
fs.mkdirSync(projectDir)
|
|
58
63
|
|
|
59
|
-
const templateDir = path.join(__dirname, 'template', template)
|
|
60
|
-
copydir.sync(templateDir, projectDir)
|
|
64
|
+
const templateDir = path.join(__dirname, 'template', template)
|
|
65
|
+
copydir.sync(templateDir, projectDir)
|
|
61
66
|
|
|
62
|
-
const packageJsonFile = path.join(projectDir, 'package.json')
|
|
63
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonFile, 'utf-8'))
|
|
64
|
-
packageJson.name = projectName
|
|
65
|
-
packageJson.description = description
|
|
66
|
-
fs.writeFileSync(packageJsonFile, JSON.stringify(packageJson, null, 2))
|
|
67
|
+
const packageJsonFile = path.join(projectDir, 'package.json')
|
|
68
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonFile, 'utf-8'))
|
|
69
|
+
packageJson.name = projectName
|
|
70
|
+
packageJson.description = description
|
|
71
|
+
fs.writeFileSync(packageJsonFile, JSON.stringify(packageJson, null, 2))
|
|
67
72
|
|
|
68
|
-
const siteConfigFile = path.join(projectDir, 'src', 'lib', 'siteConfig.ts')
|
|
69
|
-
let siteConfig = fs.readFileSync(siteConfigFile, 'utf-8')
|
|
70
|
-
siteConfig = siteConfig.replace('Project Name', projectName)
|
|
71
|
-
siteConfig = siteConfig.replace('Project Description', description)
|
|
72
|
-
fs.writeFileSync(siteConfigFile, siteConfig)
|
|
73
|
+
const siteConfigFile = path.join(projectDir, 'src', 'lib', 'siteConfig.ts')
|
|
74
|
+
let siteConfig = fs.readFileSync(siteConfigFile, 'utf-8')
|
|
75
|
+
siteConfig = siteConfig.replace('Project Name', projectName)
|
|
76
|
+
siteConfig = siteConfig.replace('Project Description', description)
|
|
77
|
+
fs.writeFileSync(siteConfigFile, siteConfig)
|
|
73
78
|
|
|
74
|
-
const envExampleFile = path.join(projectDir, '.env.example')
|
|
75
|
-
const envExample = fs.readFileSync(envExampleFile, 'utf-8')
|
|
76
|
-
fs.writeFileSync(path.join(projectDir, '.env'), envExample)
|
|
79
|
+
const envExampleFile = path.join(projectDir, '.env.example')
|
|
80
|
+
const envExample = fs.readFileSync(envExampleFile, 'utf-8')
|
|
81
|
+
fs.writeFileSync(path.join(projectDir, '.env'), envExample)
|
|
77
82
|
|
|
78
|
-
console.log(
|
|
79
|
-
}
|
|
83
|
+
console.log(
|
|
84
|
+
`Created a new app called '${projectName}' 🎉\n\nTo get started, run the following commands:\n\ncd ${projectName}\nnpm install\nnpm run dev\n`
|
|
85
|
+
)
|
|
86
|
+
})
|
|
80
87
|
|
|
81
|
-
program.parse(process.argv)
|
|
88
|
+
program.parse(process.argv)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-ej-app",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "5.0.0",
|
|
4
4
|
"description": "Bootstrap a next.js app with my preferred setup",
|
|
5
5
|
"main": "cli.js",
|
|
6
6
|
"scripts": {
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
},
|
|
31
31
|
"homepage": "https://github.com/ejekanshjain/create-ej-app#readme",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"commander": "^
|
|
33
|
+
"commander": "^14.0.2",
|
|
34
34
|
"copy-dir": "^1.3.0",
|
|
35
35
|
"enquirer": "^2.4.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@types/node": "^
|
|
39
|
-
"typescript": "^5.
|
|
38
|
+
"@types/node": "^24.10.0",
|
|
39
|
+
"typescript": "^5.9.3"
|
|
40
40
|
}
|
|
41
41
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
|
|
1
|
+
NODE_ENV="development"
|
|
2
|
+
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/postgres"
|
|
2
3
|
NEXTAUTH_SECRET="secret"
|
|
3
4
|
NEXTAUTH_URL="http://localhost:3000"
|
|
4
5
|
EMAIL_SERVER_HOST="example.com"
|
|
@@ -6,11 +7,11 @@ EMAIL_SERVER_PORT="123"
|
|
|
6
7
|
EMAIL_SERVER_USER="example@example.com"
|
|
7
8
|
EMAIL_SERVER_PASSWORD="password"
|
|
8
9
|
EMAIL_FROM="example@example.com"
|
|
9
|
-
GOOGLE_ID=""
|
|
10
|
-
GOOGLE_SECRET=""
|
|
11
|
-
GITHUB_ID=""
|
|
12
|
-
GITHUB_SECRET=""
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
10
|
+
GOOGLE_ID="id"
|
|
11
|
+
GOOGLE_SECRET="secret"
|
|
12
|
+
GITHUB_ID="id"
|
|
13
|
+
GITHUB_SECRET="secret"
|
|
14
|
+
S3_REGION="ap-south-1"
|
|
15
|
+
S3_BUCKET="bucket"
|
|
16
|
+
S3_ACCESS_KEY="key"
|
|
17
|
+
S3_SECRET_KEY="secret"
|
|
@@ -1,24 +1,26 @@
|
|
|
1
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
2
|
-
const path = require('path')
|
|
3
|
-
|
|
4
1
|
/** @type {import("eslint").Linter.Config} */
|
|
5
2
|
const eslintConfig = {
|
|
6
|
-
overrides: [
|
|
7
|
-
{
|
|
8
|
-
extends: [],
|
|
9
|
-
files: ['*.ts', '*.tsx'],
|
|
10
|
-
parserOptions: {
|
|
11
|
-
project: path.join(__dirname, 'tsconfig.json')
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
],
|
|
15
3
|
parser: '@typescript-eslint/parser',
|
|
16
4
|
parserOptions: {
|
|
17
|
-
project:
|
|
5
|
+
project: true
|
|
18
6
|
},
|
|
19
|
-
plugins: ['@typescript-eslint'],
|
|
7
|
+
plugins: ['@typescript-eslint', 'drizzle'],
|
|
20
8
|
extends: ['next/core-web-vitals'],
|
|
21
|
-
rules: {
|
|
9
|
+
rules: {
|
|
10
|
+
'@typescript-eslint/array-type': 'off',
|
|
11
|
+
'drizzle/enforce-delete-with-where': [
|
|
12
|
+
'error',
|
|
13
|
+
{
|
|
14
|
+
drizzleObjectName: ['db', 'ctx.db']
|
|
15
|
+
}
|
|
16
|
+
],
|
|
17
|
+
'drizzle/enforce-update-with-where': [
|
|
18
|
+
'error',
|
|
19
|
+
{
|
|
20
|
+
drizzleObjectName: ['db', 'ctx.db']
|
|
21
|
+
}
|
|
22
|
+
]
|
|
23
|
+
}
|
|
22
24
|
}
|
|
23
25
|
|
|
24
26
|
module.exports = eslintConfig
|
|
@@ -1,15 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful
|
|
3
|
-
* for Docker builds.
|
|
4
|
-
*/
|
|
5
|
-
await import('./src/env.mjs')
|
|
6
|
-
|
|
7
1
|
/** @type {import('next').NextConfig} */
|
|
8
|
-
const nextConfig = {
|
|
9
|
-
i18n: {
|
|
10
|
-
locales: ['en'],
|
|
11
|
-
defaultLocale: 'en'
|
|
12
|
-
}
|
|
13
|
-
}
|
|
2
|
+
const nextConfig = {}
|
|
14
3
|
|
|
15
4
|
export default nextConfig
|
|
@@ -4,77 +4,84 @@
|
|
|
4
4
|
"description": "A Legendary Next.js App",
|
|
5
5
|
"private": true,
|
|
6
6
|
"scripts": {
|
|
7
|
-
"
|
|
7
|
+
"format": "prettier --write \"src/**/*.{js,cjs,mjs,jsx,ts,tsx}\"",
|
|
8
8
|
"lint": "next lint",
|
|
9
9
|
"dev": "next dev",
|
|
10
10
|
"build": "next build",
|
|
11
11
|
"start": "next start",
|
|
12
|
-
"db:
|
|
13
|
-
"db:
|
|
14
|
-
"db:studio": "
|
|
12
|
+
"db:generate": "drizzle-kit generate",
|
|
13
|
+
"db:push": "drizzle-kit push",
|
|
14
|
+
"db:studio": "drizzle-kit studio"
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
|
+
"@auth/drizzle-adapter": "^1.4.1",
|
|
18
|
+
"@aws-sdk/client-s3": "^3.600.0",
|
|
19
|
+
"@aws-sdk/s3-presigned-post": "^3.600.0",
|
|
17
20
|
"@editorjs/checklist": "^1.6.0",
|
|
21
|
+
"@editorjs/code": "^2.9.0",
|
|
18
22
|
"@editorjs/delimiter": "^1.4.0",
|
|
19
|
-
"@editorjs/editorjs": "^2.
|
|
23
|
+
"@editorjs/editorjs": "^2.29.1",
|
|
20
24
|
"@editorjs/header": "^2.8.1",
|
|
21
25
|
"@editorjs/image": "^2.9.0",
|
|
26
|
+
"@editorjs/inline-code": "^1.5.0",
|
|
22
27
|
"@editorjs/list": "^1.9.0",
|
|
28
|
+
"@editorjs/nested-list": "^1.4.2",
|
|
23
29
|
"@editorjs/quote": "^2.6.0",
|
|
24
30
|
"@editorjs/table": "^2.3.0",
|
|
25
|
-
"@
|
|
26
|
-
"@
|
|
27
|
-
"@
|
|
28
|
-
"@
|
|
29
|
-
"@radix-ui/react-
|
|
30
|
-
"@radix-ui/react-
|
|
31
|
-
"@radix-ui/react-
|
|
32
|
-
"@radix-ui/react-
|
|
33
|
-
"@radix-ui/react-
|
|
34
|
-
"@radix-ui/react-
|
|
35
|
-
"@radix-ui/react-
|
|
36
|
-
"@radix-ui/react-
|
|
37
|
-
"@
|
|
38
|
-
"@
|
|
39
|
-
"@
|
|
40
|
-
"@
|
|
41
|
-
"@
|
|
42
|
-
"@
|
|
43
|
-
"@types/
|
|
44
|
-
"@types/
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"@types/react": "^18.2.46",
|
|
48
|
-
"@types/react-dom": "^18.2.18",
|
|
49
|
-
"@typescript-eslint/eslint-plugin": "^6.16.0",
|
|
50
|
-
"@typescript-eslint/parser": "^6.16.0",
|
|
51
|
-
"@vercel/analytics": "^1.1.1",
|
|
52
|
-
"@vercel/speed-insights": "^1.0.2",
|
|
53
|
-
"autoprefixer": "^10.4.16",
|
|
31
|
+
"@hookform/resolvers": "^3.6.0",
|
|
32
|
+
"@paralleldrive/cuid2": "^2.2.2",
|
|
33
|
+
"@radix-ui/react-alert-dialog": "^1.1.1",
|
|
34
|
+
"@radix-ui/react-avatar": "^1.1.0",
|
|
35
|
+
"@radix-ui/react-checkbox": "^1.1.0",
|
|
36
|
+
"@radix-ui/react-dialog": "^1.1.1",
|
|
37
|
+
"@radix-ui/react-dropdown-menu": "^2.1.1",
|
|
38
|
+
"@radix-ui/react-label": "^2.1.0",
|
|
39
|
+
"@radix-ui/react-popover": "^1.1.1",
|
|
40
|
+
"@radix-ui/react-select": "^2.1.1",
|
|
41
|
+
"@radix-ui/react-separator": "^1.1.0",
|
|
42
|
+
"@radix-ui/react-slot": "^1.1.0",
|
|
43
|
+
"@t3-oss/env-nextjs": "^0.10.1",
|
|
44
|
+
"@tailwindcss/typography": "^0.5.13",
|
|
45
|
+
"@tanstack/react-table": "^8.17.3",
|
|
46
|
+
"@types/eslint": "^8.56.10",
|
|
47
|
+
"@types/node": "^20.14.9",
|
|
48
|
+
"@types/nodemailer": "^6.4.15",
|
|
49
|
+
"@types/react": "^18.3.3",
|
|
50
|
+
"@types/react-dom": "^18.3.0",
|
|
51
|
+
"@typescript-eslint/eslint-plugin": "^7.14.1",
|
|
52
|
+
"@typescript-eslint/parser": "^7.14.1",
|
|
54
53
|
"class-variance-authority": "^0.7.0",
|
|
55
|
-
"clsx": "^2.
|
|
56
|
-
"cmdk": "^0.
|
|
57
|
-
"dayjs": "^1.11.
|
|
54
|
+
"clsx": "^2.1.1",
|
|
55
|
+
"cmdk": "^1.0.0",
|
|
56
|
+
"dayjs": "^1.11.11",
|
|
57
|
+
"drizzle-kit": "^0.22.7",
|
|
58
|
+
"drizzle-orm": "^0.31.2",
|
|
58
59
|
"editorjs-html": "^3.4.3",
|
|
59
|
-
"eslint": "^8.
|
|
60
|
-
"eslint-config-next": "^14.
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"next
|
|
65
|
-
"next-
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"tailwindcss": "^
|
|
60
|
+
"eslint": "^8.57.0",
|
|
61
|
+
"eslint-config-next": "^14.2.4",
|
|
62
|
+
"eslint-plugin-drizzle": "^0.2.3",
|
|
63
|
+
"geist": "^1.3.0",
|
|
64
|
+
"lucide-react": "^0.397.0",
|
|
65
|
+
"next": "^14.2.4",
|
|
66
|
+
"next-auth": "^4.24.7",
|
|
67
|
+
"next-safe-action": "^7.1.3",
|
|
68
|
+
"next-themes": "^0.3.0",
|
|
69
|
+
"nextjs-toploader": "^1.6.12",
|
|
70
|
+
"nodemailer": "^6.9.14",
|
|
71
|
+
"postcss": "^8.4.38",
|
|
72
|
+
"postcss-load-config": "^6.0.1",
|
|
73
|
+
"postgres": "^3.4.4",
|
|
74
|
+
"prettier": "^3.3.2",
|
|
75
|
+
"prettier-plugin-organize-imports": "^3.2.4",
|
|
76
|
+
"prettier-plugin-tailwindcss": "^0.6.5",
|
|
77
|
+
"react": "^18.3.1",
|
|
78
|
+
"react-dom": "^18.3.1",
|
|
79
|
+
"react-hook-form": "^7.52.0",
|
|
80
|
+
"sonner": "^1.5.0",
|
|
81
|
+
"tailwind-merge": "^2.3.0",
|
|
82
|
+
"tailwindcss": "^3.4.4",
|
|
76
83
|
"tailwindcss-animate": "^1.0.7",
|
|
77
|
-
"typescript": "^5.
|
|
78
|
-
"zod": "^3.
|
|
84
|
+
"typescript": "^5.5.2",
|
|
85
|
+
"zod": "^3.23.8"
|
|
79
86
|
}
|
|
80
87
|
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** @type {import('prettier').Config & import('prettier-plugin-tailwindcss').PluginOptions} */
|
|
2
|
+
const config = {
|
|
3
|
+
plugins: ['prettier-plugin-organize-imports', 'prettier-plugin-tailwindcss'],
|
|
4
|
+
arrowParens: 'avoid',
|
|
5
|
+
trailingComma: 'none',
|
|
6
|
+
semi: false,
|
|
7
|
+
singleQuote: true,
|
|
8
|
+
tabWidth: 2
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export default config
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Metadata } from 'next'
|
|
2
|
+
import { ReactNode } from 'react'
|
|
3
|
+
|
|
4
|
+
import { siteConfig } from '@/lib/siteConfig'
|
|
5
|
+
|
|
6
|
+
export const metadata: Metadata = {
|
|
7
|
+
title: 'Dashboard' + ' | ' + siteConfig.name
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const Layout = ({ children }: { children: ReactNode }) => {
|
|
11
|
+
return <>{children}</>
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export default Layout
|
|
@@ -1,12 +1,5 @@
|
|
|
1
|
-
import { Metadata } from 'next'
|
|
2
|
-
|
|
3
1
|
import { Heading } from '@/components/heading'
|
|
4
2
|
import { Shell } from '@/components/shell'
|
|
5
|
-
import { siteConfig } from '@/lib/siteConfig'
|
|
6
|
-
|
|
7
|
-
export const metadata: Metadata = {
|
|
8
|
-
title: 'Dashboard' + ' | ' + siteConfig.name
|
|
9
|
-
}
|
|
10
3
|
|
|
11
4
|
const DashboardPage = () => {
|
|
12
5
|
return (
|
|
@@ -7,12 +7,22 @@ import { SideNav } from '@/components/side-nav'
|
|
|
7
7
|
import { SiteFooter } from '@/components/site-footer'
|
|
8
8
|
import { UserAccountNav } from '@/components/user-account-nav'
|
|
9
9
|
import { getAuthSession } from '@/lib/auth'
|
|
10
|
+
import { checkForRolePermissionUseCase } from '@/use-case/role-permission'
|
|
10
11
|
|
|
11
12
|
const Layout = async ({ children }: { children: ReactNode }) => {
|
|
12
13
|
const session = await getAuthSession()
|
|
13
14
|
|
|
14
15
|
if (!session?.user) return notFound()
|
|
15
16
|
|
|
17
|
+
const isRoot = session.user.type === 'Root'
|
|
18
|
+
const [isTask] = await Promise.all([
|
|
19
|
+
checkForRolePermissionUseCase(
|
|
20
|
+
session.user.type,
|
|
21
|
+
session.user.roleId,
|
|
22
|
+
'TaskList'
|
|
23
|
+
)
|
|
24
|
+
])
|
|
25
|
+
|
|
16
26
|
return (
|
|
17
27
|
<div className="flex min-h-screen flex-col space-y-6">
|
|
18
28
|
<header className="sticky top-0 z-40 border-b bg-background">
|
|
@@ -24,20 +34,33 @@ const Layout = async ({ children }: { children: ReactNode }) => {
|
|
|
24
34
|
title: 'Dashboard',
|
|
25
35
|
href: '/dashboard'
|
|
26
36
|
},
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
37
|
+
...(isRoot
|
|
38
|
+
? [
|
|
39
|
+
{
|
|
40
|
+
title: 'Users',
|
|
41
|
+
href: '/users'
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
title: 'Roles',
|
|
45
|
+
href: '/roles'
|
|
46
|
+
}
|
|
47
|
+
]
|
|
48
|
+
: []),
|
|
49
|
+
...(isTask
|
|
50
|
+
? [
|
|
51
|
+
{
|
|
52
|
+
title: 'Tasks',
|
|
53
|
+
href: '/tasks'
|
|
54
|
+
}
|
|
55
|
+
]
|
|
56
|
+
: [])
|
|
35
57
|
]}
|
|
36
58
|
/>
|
|
37
59
|
<div className="flex items-center justify-center space-x-4">
|
|
38
60
|
<AppNavCommand
|
|
39
61
|
modules={{
|
|
40
|
-
task: true
|
|
62
|
+
task: true,
|
|
63
|
+
root: session.user.type === 'Root'
|
|
41
64
|
}}
|
|
42
65
|
/>
|
|
43
66
|
<UserAccountNav
|
|
@@ -59,17 +82,29 @@ const Layout = async ({ children }: { children: ReactNode }) => {
|
|
|
59
82
|
href: '/dashboard',
|
|
60
83
|
icon: 'dashboard'
|
|
61
84
|
},
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
85
|
+
...(isRoot
|
|
86
|
+
? [
|
|
87
|
+
{
|
|
88
|
+
title: 'Users',
|
|
89
|
+
href: '/users',
|
|
90
|
+
icon: 'user' as const
|
|
91
|
+
},
|
|
92
|
+
{
|
|
93
|
+
title: 'Roles',
|
|
94
|
+
href: '/roles',
|
|
95
|
+
icon: 'mixer' as const
|
|
96
|
+
}
|
|
97
|
+
]
|
|
98
|
+
: []),
|
|
99
|
+
...(isTask
|
|
100
|
+
? [
|
|
101
|
+
{
|
|
102
|
+
title: 'Tasks',
|
|
103
|
+
href: '/tasks',
|
|
104
|
+
icon: 'task' as const
|
|
105
|
+
}
|
|
106
|
+
]
|
|
107
|
+
: []),
|
|
73
108
|
{
|
|
74
109
|
title: 'Settings',
|
|
75
110
|
href: '/settings',
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
'use server'
|
|
2
|
+
|
|
3
|
+
import { revalidatePath } from 'next/cache'
|
|
4
|
+
import { z } from 'zod'
|
|
5
|
+
|
|
6
|
+
import { authActionClient } from '@/lib/safe-action'
|
|
7
|
+
import {
|
|
8
|
+
createRoleUseCase,
|
|
9
|
+
deleteRoleUseCase,
|
|
10
|
+
getRoleByIdWithPermissionsUseCase,
|
|
11
|
+
updateRoleUseCase
|
|
12
|
+
} from '@/use-case/role'
|
|
13
|
+
import { RoleCreateUpdateSchema, RoleUpdateServerSchema } from './validation'
|
|
14
|
+
|
|
15
|
+
export const getRoleAction = authActionClient
|
|
16
|
+
.schema(z.string())
|
|
17
|
+
.action(async ({ parsedInput: id, ctx }) => {
|
|
18
|
+
return await getRoleByIdWithPermissionsUseCase(ctx.user.type, id)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
export const createRoleAction = authActionClient
|
|
22
|
+
.schema(RoleCreateUpdateSchema)
|
|
23
|
+
.action(async ({ parsedInput: { name, permissions }, ctx }) => {
|
|
24
|
+
const id = await createRoleUseCase(ctx.user.type, { name, permissions })
|
|
25
|
+
|
|
26
|
+
revalidatePath('/roles')
|
|
27
|
+
revalidatePath(`/roles/${id}`)
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
success: true,
|
|
31
|
+
id
|
|
32
|
+
}
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
export const updateRoleAction = authActionClient
|
|
36
|
+
.schema(RoleUpdateServerSchema)
|
|
37
|
+
.action(async ({ parsedInput: { id, name, permissions }, ctx }) => {
|
|
38
|
+
await updateRoleUseCase(ctx.user.type, { id, name, permissions })
|
|
39
|
+
|
|
40
|
+
revalidatePath('/roles')
|
|
41
|
+
revalidatePath(`/roles/${id}`)
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
success: true
|
|
45
|
+
}
|
|
46
|
+
})
|
|
47
|
+
|
|
48
|
+
export const deleteRoleAction = authActionClient
|
|
49
|
+
.schema(z.string())
|
|
50
|
+
.action(async ({ parsedInput: id, ctx }) => {
|
|
51
|
+
await deleteRoleUseCase(ctx.user.type, id)
|
|
52
|
+
|
|
53
|
+
revalidatePath('/roles')
|
|
54
|
+
revalidatePath(`/roles/${id}`)
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
success: true
|
|
58
|
+
}
|
|
59
|
+
})
|