create-ej-app 6.0.0 → 8.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/cli.js +88 -14
- package/cli.ts +100 -17
- package/package.json +2 -2
- package/template/base/.env.example +11 -15
- package/template/base/Dockerfile +15 -0
- package/template/base/components.json +10 -5
- package/template/base/drizzle.config.ts +4 -5
- package/template/{new → base}/eslint.config.mjs +6 -1
- package/template/base/package.json +58 -75
- package/template/base/postcss.config.mjs +1 -4
- package/template/base/src/app/(admin)/layout.tsx +20 -0
- package/template/base/src/app/(app)/layout.tsx +13 -118
- package/template/base/src/app/(auth)/login/page.tsx +65 -42
- package/template/base/src/app/(marketing)/layout.tsx +7 -35
- package/template/base/src/app/(marketing)/page.tsx +2 -96
- package/template/base/src/app/(marketing)/privacy/page.tsx +3 -0
- package/template/base/src/app/(marketing)/terms/page.tsx +3 -0
- package/template/base/src/app/globals.css +118 -66
- package/template/base/src/app/layout.tsx +27 -12
- package/template/base/src/app/not-found.tsx +27 -0
- package/template/base/src/components/site-footer.tsx +16 -24
- package/template/base/src/components/ui/button.tsx +31 -27
- package/template/base/src/components/ui/card.tsx +83 -70
- package/template/base/src/components/ui/form.tsx +38 -47
- package/template/base/src/components/ui/input.tsx +16 -20
- package/template/base/src/components/ui/label.tsx +16 -18
- package/template/base/src/components/ui/separator.tsx +11 -14
- package/template/base/src/components/ui/sonner.tsx +22 -13
- package/template/base/src/db/index.ts +4 -11
- package/template/base/src/db/schema.ts +60 -268
- package/template/{new → base}/src/env.ts +2 -2
- package/template/{new → base}/src/lib/auth-client.ts +2 -0
- package/template/base/src/lib/auth.ts +64 -80
- package/template/base/src/lib/safe-action.ts +30 -6
- package/template/base/tsconfig.json +9 -7
- package/template/{prisma-advanced → old}/.env.example +10 -9
- package/template/{prisma → old}/components.json +1 -1
- package/template/old/drizzle.config.ts +11 -0
- package/template/old/package.json +87 -0
- package/template/old/postcss.config.mjs +8 -0
- package/template/{prisma-advanced → old}/src/app/(app)/layout.tsx +11 -3
- package/template/{prisma-advanced → old}/src/app/(auth)/login/page.tsx +2 -2
- package/template/{prisma → old}/src/app/(marketing)/page.tsx +8 -7
- package/template/old/src/app/layout.tsx +31 -0
- package/template/old/src/components/ui/sonner.tsx +31 -0
- package/template/old/src/db/index.ts +14 -0
- package/template/old/src/db/schema.ts +287 -0
- package/template/old/src/lib/auth.ts +89 -0
- package/template/old/src/lib/safe-action.ts +19 -0
- package/template/{prisma-advanced → old}/tsconfig.json +3 -2
- package/template/new/.env.example +0 -13
- package/template/new/components.json +0 -22
- package/template/new/drizzle.config.ts +0 -10
- package/template/new/package.json +0 -81
- package/template/new/postcss.config.mjs +0 -5
- package/template/new/src/app/(auth)/login/page.tsx +0 -72
- package/template/new/src/app/globals.css +0 -128
- package/template/new/src/app/layout.tsx +0 -50
- package/template/new/src/app/page.tsx +0 -3
- package/template/new/src/components/ui/button.tsx +0 -60
- package/template/new/src/components/ui/card.tsx +0 -92
- package/template/new/src/components/ui/form.tsx +0 -167
- package/template/new/src/components/ui/input.tsx +0 -21
- package/template/new/src/components/ui/label.tsx +0 -24
- package/template/new/src/components/ui/separator.tsx +0 -28
- package/template/new/src/components/ui/sonner.tsx +0 -40
- package/template/new/src/db/index.ts +0 -7
- package/template/new/src/db/schema.ts +0 -74
- package/template/new/src/lib/auth.ts +0 -67
- package/template/new/src/lib/safe-action.ts +0 -15
- package/template/new/tsconfig.json +0 -49
- package/template/prisma/.env.example +0 -16
- package/template/prisma/.eslintrc.cjs +0 -24
- package/template/prisma/next.config.mjs +0 -15
- package/template/prisma/package.json +0 -80
- package/template/prisma/postcss.config.cjs +0 -6
- package/template/prisma/prettier.config.ts +0 -11
- package/template/prisma/prisma/schema.prisma +0 -115
- package/template/prisma/public/next.svg +0 -1
- package/template/prisma/src/app/(app)/dashboard/page.tsx +0 -19
- package/template/prisma/src/app/(app)/layout.tsx +0 -90
- package/template/prisma/src/app/(app)/settings/actions.ts +0 -18
- package/template/prisma/src/app/(app)/settings/loading.tsx +0 -28
- package/template/prisma/src/app/(app)/settings/page.tsx +0 -28
- package/template/prisma/src/app/(app)/settings/render.tsx +0 -113
- package/template/prisma/src/app/(app)/tasks/[id]/actions.ts +0 -147
- package/template/prisma/src/app/(app)/tasks/[id]/page.tsx +0 -25
- package/template/prisma/src/app/(app)/tasks/[id]/render.tsx +0 -413
- package/template/prisma/src/app/(app)/tasks/actions.ts +0 -69
- package/template/prisma/src/app/(app)/tasks/page.tsx +0 -53
- package/template/prisma/src/app/(app)/tasks/render.tsx +0 -107
- package/template/prisma/src/app/(app)/users/[id]/actions.ts +0 -83
- package/template/prisma/src/app/(app)/users/[id]/page.tsx +0 -32
- package/template/prisma/src/app/(app)/users/[id]/render.tsx +0 -240
- package/template/prisma/src/app/(app)/users/actions.ts +0 -55
- package/template/prisma/src/app/(app)/users/page.tsx +0 -49
- package/template/prisma/src/app/(app)/users/render.tsx +0 -80
- package/template/prisma/src/app/(auth)/layout.tsx +0 -20
- package/template/prisma/src/app/(auth)/login/page.tsx +0 -49
- package/template/prisma/src/app/(auth)/login/user-auth-form.tsx +0 -152
- package/template/prisma/src/app/api/auth/[...nextauth]/route.ts +0 -7
- package/template/prisma/src/app/api/upload/route.ts +0 -36
- package/template/prisma/src/app/favicon.ico +0 -0
- package/template/prisma/src/app/layout.tsx +0 -34
- package/template/prisma/src/components/app-nav-command.tsx +0 -160
- package/template/prisma/src/components/dark-mode-toggle.tsx +0 -43
- package/template/prisma/src/components/data-table/data-table-column-header.tsx +0 -91
- package/template/prisma/src/components/data-table/data-table-faceted-filter.tsx +0 -149
- package/template/prisma/src/components/data-table/data-table-loading.tsx +0 -77
- package/template/prisma/src/components/data-table/data-table-pagination.tsx +0 -94
- package/template/prisma/src/components/data-table/data-table-toolbar.tsx +0 -78
- package/template/prisma/src/components/data-table/data-table-types.ts +0 -17
- package/template/prisma/src/components/data-table/data-table-view-options.tsx +0 -59
- package/template/prisma/src/components/data-table/data-table.tsx +0 -301
- package/template/prisma/src/components/data-table/simple-data-table.tsx +0 -109
- package/template/prisma/src/components/empty-placeholder.tsx +0 -78
- package/template/prisma/src/components/heading.tsx +0 -17
- package/template/prisma/src/components/icons.tsx +0 -85
- package/template/prisma/src/components/main-nav.tsx +0 -64
- package/template/prisma/src/components/mobile-nav.tsx +0 -50
- package/template/prisma/src/components/shell.tsx +0 -13
- package/template/prisma/src/components/side-nav.tsx +0 -51
- package/template/prisma/src/components/site-footer.tsx +0 -31
- package/template/prisma/src/components/system-info.tsx +0 -36
- package/template/prisma/src/components/theme-provider.tsx +0 -13
- package/template/prisma/src/components/ui/alert-dialog.tsx +0 -141
- package/template/prisma/src/components/ui/avatar.tsx +0 -50
- package/template/prisma/src/components/ui/badge.tsx +0 -36
- package/template/prisma/src/components/ui/button.tsx +0 -56
- package/template/prisma/src/components/ui/card.tsx +0 -79
- package/template/prisma/src/components/ui/checkbox.tsx +0 -30
- package/template/prisma/src/components/ui/command.tsx +0 -155
- package/template/prisma/src/components/ui/dialog.tsx +0 -122
- package/template/prisma/src/components/ui/dropdown-menu.tsx +0 -200
- package/template/prisma/src/components/ui/form.tsx +0 -176
- package/template/prisma/src/components/ui/input.tsx +0 -25
- package/template/prisma/src/components/ui/label.tsx +0 -26
- package/template/prisma/src/components/ui/popover.tsx +0 -31
- package/template/prisma/src/components/ui/select.tsx +0 -160
- package/template/prisma/src/components/ui/separator.tsx +0 -31
- package/template/prisma/src/components/ui/skeleton.tsx +0 -15
- package/template/prisma/src/components/ui/table.tsx +0 -117
- package/template/prisma/src/components/ui/textarea.tsx +0 -24
- package/template/prisma/src/components/ui/toast.tsx +0 -127
- package/template/prisma/src/components/ui/toaster.tsx +0 -35
- package/template/prisma/src/components/ui/use-toast.ts +0 -189
- package/template/prisma/src/components/user-account-nav.tsx +0 -60
- package/template/prisma/src/components/user-avatar.tsx +0 -25
- package/template/prisma/src/env.mjs +0 -78
- package/template/prisma/src/hooks/use-debounce.ts +0 -17
- package/template/prisma/src/hooks/use-lock-body.tsx +0 -12
- package/template/prisma/src/lib/auth.ts +0 -80
- package/template/prisma/src/lib/cn.ts +0 -4
- package/template/prisma/src/lib/db.ts +0 -20
- package/template/prisma/src/lib/delay.ts +0 -2
- package/template/prisma/src/lib/formatDate.ts +0 -11
- package/template/prisma/src/lib/generateLabel.ts +0 -5
- package/template/prisma/src/lib/siteConfig.ts +0 -4
- package/template/prisma/src/lib/storageClient.ts +0 -11
- package/template/prisma/src/styles/editor.css +0 -61
- package/template/prisma/src/styles/globals.css +0 -76
- package/template/prisma/src/types/UnwrapPromise.ts +0 -1
- package/template/prisma/tailwind.config.ts +0 -80
- package/template/prisma/tsconfig.json +0 -46
- package/template/prisma-advanced/.eslintrc.cjs +0 -24
- package/template/prisma-advanced/components.json +0 -17
- package/template/prisma-advanced/next.config.mjs +0 -15
- package/template/prisma-advanced/package.json +0 -80
- package/template/prisma-advanced/postcss.config.cjs +0 -6
- package/template/prisma-advanced/prettier.config.ts +0 -11
- package/template/prisma-advanced/prisma/schema.prisma +0 -154
- package/template/prisma-advanced/public/next.svg +0 -1
- package/template/prisma-advanced/src/app/(app)/dashboard/page.tsx +0 -19
- package/template/prisma-advanced/src/app/(app)/roles/[id]/actions.ts +0 -100
- package/template/prisma-advanced/src/app/(app)/roles/[id]/page.tsx +0 -36
- package/template/prisma-advanced/src/app/(app)/roles/[id]/render.tsx +0 -266
- package/template/prisma-advanced/src/app/(app)/roles/actions.ts +0 -67
- package/template/prisma-advanced/src/app/(app)/roles/page.tsx +0 -51
- package/template/prisma-advanced/src/app/(app)/roles/render.tsx +0 -70
- package/template/prisma-advanced/src/app/(app)/settings/actions.ts +0 -18
- package/template/prisma-advanced/src/app/(app)/settings/loading.tsx +0 -28
- package/template/prisma-advanced/src/app/(app)/settings/page.tsx +0 -28
- package/template/prisma-advanced/src/app/(app)/settings/render.tsx +0 -113
- package/template/prisma-advanced/src/app/(app)/tasks/[id]/actions.ts +0 -147
- package/template/prisma-advanced/src/app/(app)/tasks/[id]/page.tsx +0 -55
- package/template/prisma-advanced/src/app/(app)/tasks/[id]/render.tsx +0 -418
- package/template/prisma-advanced/src/app/(app)/tasks/actions.ts +0 -69
- package/template/prisma-advanced/src/app/(app)/tasks/page.tsx +0 -63
- package/template/prisma-advanced/src/app/(app)/tasks/render.tsx +0 -114
- package/template/prisma-advanced/src/app/(app)/users/[id]/actions.ts +0 -104
- package/template/prisma-advanced/src/app/(app)/users/[id]/page.tsx +0 -39
- package/template/prisma-advanced/src/app/(app)/users/[id]/render.tsx +0 -320
- package/template/prisma-advanced/src/app/(app)/users/actions.ts +0 -67
- package/template/prisma-advanced/src/app/(app)/users/page.tsx +0 -61
- package/template/prisma-advanced/src/app/(app)/users/render.tsx +0 -108
- package/template/prisma-advanced/src/app/(auth)/layout.tsx +0 -20
- package/template/prisma-advanced/src/app/(auth)/login/user-auth-form.tsx +0 -152
- package/template/prisma-advanced/src/app/(marketing)/layout.tsx +0 -42
- package/template/prisma-advanced/src/app/(marketing)/page.tsx +0 -96
- package/template/prisma-advanced/src/app/api/auth/[...nextauth]/route.ts +0 -7
- package/template/prisma-advanced/src/app/api/upload/route.ts +0 -36
- package/template/prisma-advanced/src/app/favicon.ico +0 -0
- package/template/prisma-advanced/src/app/layout.tsx +0 -34
- package/template/prisma-advanced/src/components/app-nav-command.tsx +0 -160
- package/template/prisma-advanced/src/components/dark-mode-toggle.tsx +0 -43
- package/template/prisma-advanced/src/components/data-table/data-table-column-header.tsx +0 -91
- package/template/prisma-advanced/src/components/data-table/data-table-faceted-filter.tsx +0 -149
- package/template/prisma-advanced/src/components/data-table/data-table-loading.tsx +0 -77
- package/template/prisma-advanced/src/components/data-table/data-table-pagination.tsx +0 -94
- package/template/prisma-advanced/src/components/data-table/data-table-toolbar.tsx +0 -78
- package/template/prisma-advanced/src/components/data-table/data-table-types.ts +0 -17
- package/template/prisma-advanced/src/components/data-table/data-table-view-options.tsx +0 -59
- package/template/prisma-advanced/src/components/data-table/data-table.tsx +0 -301
- package/template/prisma-advanced/src/components/data-table/simple-data-table.tsx +0 -109
- package/template/prisma-advanced/src/components/empty-placeholder.tsx +0 -78
- package/template/prisma-advanced/src/components/heading.tsx +0 -17
- package/template/prisma-advanced/src/components/icons.tsx +0 -85
- package/template/prisma-advanced/src/components/main-nav.tsx +0 -64
- package/template/prisma-advanced/src/components/shell.tsx +0 -13
- package/template/prisma-advanced/src/components/side-nav.tsx +0 -51
- package/template/prisma-advanced/src/components/system-info.tsx +0 -36
- package/template/prisma-advanced/src/components/theme-provider.tsx +0 -13
- package/template/prisma-advanced/src/components/ui/alert-dialog.tsx +0 -141
- package/template/prisma-advanced/src/components/ui/avatar.tsx +0 -50
- package/template/prisma-advanced/src/components/ui/badge.tsx +0 -36
- package/template/prisma-advanced/src/components/ui/checkbox.tsx +0 -30
- package/template/prisma-advanced/src/components/ui/command.tsx +0 -155
- package/template/prisma-advanced/src/components/ui/dialog.tsx +0 -122
- package/template/prisma-advanced/src/components/ui/dropdown-menu.tsx +0 -200
- package/template/prisma-advanced/src/components/ui/popover.tsx +0 -31
- package/template/prisma-advanced/src/components/ui/select.tsx +0 -160
- package/template/prisma-advanced/src/components/ui/skeleton.tsx +0 -15
- package/template/prisma-advanced/src/components/ui/table.tsx +0 -117
- package/template/prisma-advanced/src/components/ui/textarea.tsx +0 -24
- package/template/prisma-advanced/src/components/ui/toast.tsx +0 -127
- package/template/prisma-advanced/src/components/ui/toaster.tsx +0 -35
- package/template/prisma-advanced/src/components/ui/use-toast.ts +0 -189
- package/template/prisma-advanced/src/components/user-account-nav.tsx +0 -60
- package/template/prisma-advanced/src/components/user-avatar.tsx +0 -25
- package/template/prisma-advanced/src/env.mjs +0 -78
- package/template/prisma-advanced/src/hooks/use-debounce.ts +0 -17
- package/template/prisma-advanced/src/hooks/use-lock-body.tsx +0 -12
- package/template/prisma-advanced/src/lib/auth.ts +0 -180
- package/template/prisma-advanced/src/lib/cn.ts +0 -4
- package/template/prisma-advanced/src/lib/db.ts +0 -20
- package/template/prisma-advanced/src/lib/delay.ts +0 -2
- package/template/prisma-advanced/src/lib/formatDate.ts +0 -11
- package/template/prisma-advanced/src/lib/generateLabel.ts +0 -5
- package/template/prisma-advanced/src/lib/siteConfig.ts +0 -4
- package/template/prisma-advanced/src/lib/storageClient.ts +0 -11
- package/template/prisma-advanced/src/styles/editor.css +0 -61
- package/template/prisma-advanced/src/types/UnwrapPromise.ts +0 -1
- package/template/prisma-advanced/tailwind.config.ts +0 -80
- package/template/{new → base}/next.config.ts +0 -0
- package/template/{new → base}/public/placeholder.svg +0 -0
- package/template/{new → base}/src/app/(auth)/login/email-login-form.tsx +0 -0
- package/template/{new → base}/src/app/(auth)/login/social-login-buttons.tsx +0 -0
- package/template/{new → base}/src/app/api/auth/[...all]/route.ts +0 -0
- package/template/{new → base}/src/components/loader.tsx +0 -0
- package/template/{new → base}/src/components/react-query-provider.tsx +0 -0
- package/template/{new → base}/src/components/screen-size.tsx +0 -0
- package/template/{new → base}/src/components/theme-toggle.tsx +0 -0
- package/template/{new → base}/src/lib/toast-message.ts +0 -0
- package/template/{base → old}/.eslintrc.cjs +0 -0
- package/template/{base → old}/next.config.mjs +0 -0
- package/template/{new → old}/prettier.config.mjs +0 -0
- package/template/{base → old}/public/next.svg +0 -0
- package/template/{base → old}/public/vercel.svg +0 -0
- package/template/{base → old}/src/app/(app)/dashboard/layout.tsx +0 -0
- package/template/{base → old}/src/app/(app)/dashboard/page.tsx +0 -0
- package/template/{base → old}/src/app/(app)/roles/[id]/actions.ts +0 -0
- package/template/{base → old}/src/app/(app)/roles/[id]/page.tsx +0 -0
- package/template/{base → old}/src/app/(app)/roles/[id]/render.tsx +0 -0
- package/template/{base → old}/src/app/(app)/roles/[id]/validation.ts +0 -0
- package/template/{base → old}/src/app/(app)/roles/actions.ts +0 -0
- package/template/{base → old}/src/app/(app)/roles/page.tsx +0 -0
- package/template/{base → old}/src/app/(app)/roles/render.tsx +0 -0
- package/template/{base → old}/src/app/(app)/settings/actions.ts +0 -0
- package/template/{base → old}/src/app/(app)/settings/layout.tsx +0 -0
- package/template/{base → old}/src/app/(app)/settings/loading.tsx +0 -0
- package/template/{base → old}/src/app/(app)/settings/page.tsx +0 -0
- package/template/{base → old}/src/app/(app)/settings/render.tsx +0 -0
- package/template/{base → old}/src/app/(app)/settings/validation.ts +0 -0
- package/template/{base → old}/src/app/(app)/tasks/[id]/actions.ts +0 -0
- package/template/{base → old}/src/app/(app)/tasks/[id]/page.tsx +0 -0
- package/template/{base → old}/src/app/(app)/tasks/[id]/render.tsx +0 -0
- package/template/{base → old}/src/app/(app)/tasks/[id]/validation.ts +0 -0
- package/template/{base → old}/src/app/(app)/tasks/actions.ts +0 -0
- package/template/{base → old}/src/app/(app)/tasks/page.tsx +0 -0
- package/template/{base → old}/src/app/(app)/tasks/render.tsx +0 -0
- package/template/{base → old}/src/app/(app)/tasks/statusEnum.ts +0 -0
- package/template/{base → old}/src/app/(app)/users/[id]/actions.ts +0 -0
- package/template/{base → old}/src/app/(app)/users/[id]/page.tsx +0 -0
- package/template/{base → old}/src/app/(app)/users/[id]/render.tsx +0 -0
- package/template/{base → old}/src/app/(app)/users/[id]/validation.ts +0 -0
- package/template/{base → old}/src/app/(app)/users/actions.ts +0 -0
- package/template/{base → old}/src/app/(app)/users/page.tsx +0 -0
- package/template/{base → old}/src/app/(app)/users/render.tsx +0 -0
- package/template/{base → old}/src/app/(auth)/layout.tsx +0 -0
- package/template/{base → old}/src/app/(auth)/login/render.tsx +0 -0
- package/template/{prisma → old}/src/app/(marketing)/layout.tsx +1 -1
- /package/template/{base → old}/src/app/api/auth/[...nextauth]/route.ts +0 -0
- /package/template/{new → old}/src/app/favicon.ico +0 -0
- /package/template/{prisma-advanced/src/styles → old/src/app}/globals.css +0 -0
- /package/template/{base → old}/src/components/app-nav-command.tsx +0 -0
- /package/template/{base → old}/src/components/dark-mode-toggle.tsx +0 -0
- /package/template/{base → old}/src/components/data-table/data-table-column-header.tsx +0 -0
- /package/template/{base → old}/src/components/data-table/data-table-faceted-filter.tsx +0 -0
- /package/template/{base → old}/src/components/data-table/data-table-loading.tsx +0 -0
- /package/template/{base → old}/src/components/data-table/data-table-pagination.tsx +0 -0
- /package/template/{base → old}/src/components/data-table/data-table-toolbar.tsx +0 -0
- /package/template/{base → old}/src/components/data-table/data-table-types.ts +0 -0
- /package/template/{base → old}/src/components/data-table/data-table-view-options.tsx +0 -0
- /package/template/{base → old}/src/components/data-table/data-table.tsx +0 -0
- /package/template/{base → old}/src/components/data-table/simple-data-table.tsx +0 -0
- /package/template/{base → old}/src/components/empty-placeholder.tsx +0 -0
- /package/template/{base → old}/src/components/heading.tsx +0 -0
- /package/template/{base → old}/src/components/icons.tsx +0 -0
- /package/template/{base → old}/src/components/main-nav.tsx +0 -0
- /package/template/{base → old}/src/components/mobile-nav.tsx +0 -0
- /package/template/{base → old}/src/components/shell.tsx +0 -0
- /package/template/{base → old}/src/components/side-nav.tsx +0 -0
- /package/template/{prisma-advanced → old}/src/components/site-footer.tsx +0 -0
- /package/template/{base → old}/src/components/system-info.tsx +0 -0
- /package/template/{base → old}/src/components/ui/alert-dialog.tsx +0 -0
- /package/template/{base → old}/src/components/ui/avatar.tsx +0 -0
- /package/template/{base → old}/src/components/ui/badge.tsx +0 -0
- /package/template/{prisma-advanced → old}/src/components/ui/button.tsx +0 -0
- /package/template/{prisma-advanced → old}/src/components/ui/card.tsx +0 -0
- /package/template/{base → old}/src/components/ui/checkbox.tsx +0 -0
- /package/template/{base → old}/src/components/ui/command.tsx +0 -0
- /package/template/{base → old}/src/components/ui/dialog.tsx +0 -0
- /package/template/{base → old}/src/components/ui/dropdown-menu.tsx +0 -0
- /package/template/{prisma-advanced → old}/src/components/ui/form.tsx +0 -0
- /package/template/{prisma-advanced → old}/src/components/ui/input.tsx +0 -0
- /package/template/{prisma-advanced → old}/src/components/ui/label.tsx +0 -0
- /package/template/{base → old}/src/components/ui/popover.tsx +0 -0
- /package/template/{base → old}/src/components/ui/select.tsx +0 -0
- /package/template/{prisma-advanced → old}/src/components/ui/separator.tsx +0 -0
- /package/template/{base → old}/src/components/ui/skeleton.tsx +0 -0
- /package/template/{base → old}/src/components/ui/table.tsx +0 -0
- /package/template/{base → old}/src/components/user-account-nav.tsx +0 -0
- /package/template/{base → old}/src/components/user-avatar.tsx +0 -0
- /package/template/{base → old}/src/data-access/resource.ts +0 -0
- /package/template/{base → old}/src/data-access/role-permission.ts +0 -0
- /package/template/{base → old}/src/data-access/role.ts +0 -0
- /package/template/{base → old}/src/data-access/task.ts +0 -0
- /package/template/{base → old}/src/data-access/user.ts +0 -0
- /package/template/{base → old}/src/env.mjs +0 -0
- /package/template/{base → old}/src/hooks/use-debounce.tsx +0 -0
- /package/template/{base → old}/src/hooks/use-lock-body.tsx +0 -0
- /package/template/{new → old}/src/lib/cn.ts +0 -0
- /package/template/{base → old}/src/lib/currentUser.ts +0 -0
- /package/template/{new → old}/src/lib/delay.ts +0 -0
- /package/template/{base → old}/src/lib/formatDate.ts +0 -0
- /package/template/{base → old}/src/lib/generateLabel.ts +0 -0
- /package/template/{base → old}/src/lib/s3Client.ts +0 -0
- /package/template/{new → old}/src/lib/siteConfig.ts +0 -0
- /package/template/{base → old}/src/lib/sortOrderEnum.ts +0 -0
- /package/template/{base → old}/src/use-case/role-permission.ts +0 -0
- /package/template/{base → old}/src/use-case/role.ts +0 -0
- /package/template/{base → old}/src/use-case/task.ts +0 -0
- /package/template/{base → old}/src/use-case/user.ts +0 -0
- /package/template/{base → old}/tailwind.config.ts +0 -0
|
@@ -1,117 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
|
|
3
|
-
import { cn } from '@/lib/cn'
|
|
4
|
-
|
|
5
|
-
const Table = React.forwardRef<
|
|
6
|
-
HTMLTableElement,
|
|
7
|
-
React.HTMLAttributes<HTMLTableElement>
|
|
8
|
-
>(({ className, ...props }, ref) => (
|
|
9
|
-
<div className="relative w-full overflow-auto">
|
|
10
|
-
<table
|
|
11
|
-
ref={ref}
|
|
12
|
-
className={cn('w-full caption-bottom text-sm', className)}
|
|
13
|
-
{...props}
|
|
14
|
-
/>
|
|
15
|
-
</div>
|
|
16
|
-
))
|
|
17
|
-
Table.displayName = 'Table'
|
|
18
|
-
|
|
19
|
-
const TableHeader = React.forwardRef<
|
|
20
|
-
HTMLTableSectionElement,
|
|
21
|
-
React.HTMLAttributes<HTMLTableSectionElement>
|
|
22
|
-
>(({ className, ...props }, ref) => (
|
|
23
|
-
<thead ref={ref} className={cn('[&_tr]:border-b', className)} {...props} />
|
|
24
|
-
))
|
|
25
|
-
TableHeader.displayName = 'TableHeader'
|
|
26
|
-
|
|
27
|
-
const TableBody = React.forwardRef<
|
|
28
|
-
HTMLTableSectionElement,
|
|
29
|
-
React.HTMLAttributes<HTMLTableSectionElement>
|
|
30
|
-
>(({ className, ...props }, ref) => (
|
|
31
|
-
<tbody
|
|
32
|
-
ref={ref}
|
|
33
|
-
className={cn('[&_tr:last-child]:border-0', className)}
|
|
34
|
-
{...props}
|
|
35
|
-
/>
|
|
36
|
-
))
|
|
37
|
-
TableBody.displayName = 'TableBody'
|
|
38
|
-
|
|
39
|
-
const TableFooter = React.forwardRef<
|
|
40
|
-
HTMLTableSectionElement,
|
|
41
|
-
React.HTMLAttributes<HTMLTableSectionElement>
|
|
42
|
-
>(({ className, ...props }, ref) => (
|
|
43
|
-
<tfoot
|
|
44
|
-
ref={ref}
|
|
45
|
-
className={cn(
|
|
46
|
-
'border-t bg-muted/50 font-medium [&>tr]:last:border-b-0',
|
|
47
|
-
className
|
|
48
|
-
)}
|
|
49
|
-
{...props}
|
|
50
|
-
/>
|
|
51
|
-
))
|
|
52
|
-
TableFooter.displayName = 'TableFooter'
|
|
53
|
-
|
|
54
|
-
const TableRow = React.forwardRef<
|
|
55
|
-
HTMLTableRowElement,
|
|
56
|
-
React.HTMLAttributes<HTMLTableRowElement>
|
|
57
|
-
>(({ className, ...props }, ref) => (
|
|
58
|
-
<tr
|
|
59
|
-
ref={ref}
|
|
60
|
-
className={cn(
|
|
61
|
-
'border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted',
|
|
62
|
-
className
|
|
63
|
-
)}
|
|
64
|
-
{...props}
|
|
65
|
-
/>
|
|
66
|
-
))
|
|
67
|
-
TableRow.displayName = 'TableRow'
|
|
68
|
-
|
|
69
|
-
const TableHead = React.forwardRef<
|
|
70
|
-
HTMLTableCellElement,
|
|
71
|
-
React.ThHTMLAttributes<HTMLTableCellElement>
|
|
72
|
-
>(({ className, ...props }, ref) => (
|
|
73
|
-
<th
|
|
74
|
-
ref={ref}
|
|
75
|
-
className={cn(
|
|
76
|
-
'h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0',
|
|
77
|
-
className
|
|
78
|
-
)}
|
|
79
|
-
{...props}
|
|
80
|
-
/>
|
|
81
|
-
))
|
|
82
|
-
TableHead.displayName = 'TableHead'
|
|
83
|
-
|
|
84
|
-
const TableCell = React.forwardRef<
|
|
85
|
-
HTMLTableCellElement,
|
|
86
|
-
React.TdHTMLAttributes<HTMLTableCellElement>
|
|
87
|
-
>(({ className, ...props }, ref) => (
|
|
88
|
-
<td
|
|
89
|
-
ref={ref}
|
|
90
|
-
className={cn('p-4 align-middle [&:has([role=checkbox])]:pr-0', className)}
|
|
91
|
-
{...props}
|
|
92
|
-
/>
|
|
93
|
-
))
|
|
94
|
-
TableCell.displayName = 'TableCell'
|
|
95
|
-
|
|
96
|
-
const TableCaption = React.forwardRef<
|
|
97
|
-
HTMLTableCaptionElement,
|
|
98
|
-
React.HTMLAttributes<HTMLTableCaptionElement>
|
|
99
|
-
>(({ className, ...props }, ref) => (
|
|
100
|
-
<caption
|
|
101
|
-
ref={ref}
|
|
102
|
-
className={cn('mt-4 text-sm text-muted-foreground', className)}
|
|
103
|
-
{...props}
|
|
104
|
-
/>
|
|
105
|
-
))
|
|
106
|
-
TableCaption.displayName = 'TableCaption'
|
|
107
|
-
|
|
108
|
-
export {
|
|
109
|
-
Table,
|
|
110
|
-
TableBody,
|
|
111
|
-
TableCaption,
|
|
112
|
-
TableCell,
|
|
113
|
-
TableFooter,
|
|
114
|
-
TableHead,
|
|
115
|
-
TableHeader,
|
|
116
|
-
TableRow
|
|
117
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
|
|
3
|
-
import { cn } from '@/lib/cn'
|
|
4
|
-
|
|
5
|
-
export interface TextareaProps
|
|
6
|
-
extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {}
|
|
7
|
-
|
|
8
|
-
const Textarea = React.forwardRef<HTMLTextAreaElement, TextareaProps>(
|
|
9
|
-
({ className, ...props }, ref) => {
|
|
10
|
-
return (
|
|
11
|
-
<textarea
|
|
12
|
-
className={cn(
|
|
13
|
-
'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',
|
|
14
|
-
className
|
|
15
|
-
)}
|
|
16
|
-
ref={ref}
|
|
17
|
-
{...props}
|
|
18
|
-
/>
|
|
19
|
-
)
|
|
20
|
-
}
|
|
21
|
-
)
|
|
22
|
-
Textarea.displayName = 'Textarea'
|
|
23
|
-
|
|
24
|
-
export { Textarea }
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
import * as ToastPrimitives from '@radix-ui/react-toast'
|
|
2
|
-
import { cva, type VariantProps } from 'class-variance-authority'
|
|
3
|
-
import { X } from 'lucide-react'
|
|
4
|
-
import * as React from 'react'
|
|
5
|
-
|
|
6
|
-
import { cn } from '@/lib/cn'
|
|
7
|
-
|
|
8
|
-
const ToastProvider = ToastPrimitives.Provider
|
|
9
|
-
|
|
10
|
-
const ToastViewport = React.forwardRef<
|
|
11
|
-
React.ElementRef<typeof ToastPrimitives.Viewport>,
|
|
12
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>
|
|
13
|
-
>(({ className, ...props }, ref) => (
|
|
14
|
-
<ToastPrimitives.Viewport
|
|
15
|
-
ref={ref}
|
|
16
|
-
className={cn(
|
|
17
|
-
'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]',
|
|
18
|
-
className
|
|
19
|
-
)}
|
|
20
|
-
{...props}
|
|
21
|
-
/>
|
|
22
|
-
))
|
|
23
|
-
ToastViewport.displayName = ToastPrimitives.Viewport.displayName
|
|
24
|
-
|
|
25
|
-
const toastVariants = cva(
|
|
26
|
-
'group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 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',
|
|
27
|
-
{
|
|
28
|
-
variants: {
|
|
29
|
-
variant: {
|
|
30
|
-
default: 'border bg-background text-foreground',
|
|
31
|
-
destructive:
|
|
32
|
-
'destructive group border-destructive bg-destructive text-destructive-foreground'
|
|
33
|
-
}
|
|
34
|
-
},
|
|
35
|
-
defaultVariants: {
|
|
36
|
-
variant: 'default'
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
)
|
|
40
|
-
|
|
41
|
-
const Toast = React.forwardRef<
|
|
42
|
-
React.ElementRef<typeof ToastPrimitives.Root>,
|
|
43
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &
|
|
44
|
-
VariantProps<typeof toastVariants>
|
|
45
|
-
>(({ className, variant, ...props }, ref) => {
|
|
46
|
-
return (
|
|
47
|
-
<ToastPrimitives.Root
|
|
48
|
-
ref={ref}
|
|
49
|
-
className={cn(toastVariants({ variant }), className)}
|
|
50
|
-
{...props}
|
|
51
|
-
/>
|
|
52
|
-
)
|
|
53
|
-
})
|
|
54
|
-
Toast.displayName = ToastPrimitives.Root.displayName
|
|
55
|
-
|
|
56
|
-
const ToastAction = React.forwardRef<
|
|
57
|
-
React.ElementRef<typeof ToastPrimitives.Action>,
|
|
58
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>
|
|
59
|
-
>(({ className, ...props }, ref) => (
|
|
60
|
-
<ToastPrimitives.Action
|
|
61
|
-
ref={ref}
|
|
62
|
-
className={cn(
|
|
63
|
-
'inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 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',
|
|
64
|
-
className
|
|
65
|
-
)}
|
|
66
|
-
{...props}
|
|
67
|
-
/>
|
|
68
|
-
))
|
|
69
|
-
ToastAction.displayName = ToastPrimitives.Action.displayName
|
|
70
|
-
|
|
71
|
-
const ToastClose = React.forwardRef<
|
|
72
|
-
React.ElementRef<typeof ToastPrimitives.Close>,
|
|
73
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>
|
|
74
|
-
>(({ className, ...props }, ref) => (
|
|
75
|
-
<ToastPrimitives.Close
|
|
76
|
-
ref={ref}
|
|
77
|
-
className={cn(
|
|
78
|
-
'absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 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',
|
|
79
|
-
className
|
|
80
|
-
)}
|
|
81
|
-
toast-close=""
|
|
82
|
-
{...props}
|
|
83
|
-
>
|
|
84
|
-
<X className="h-4 w-4" />
|
|
85
|
-
</ToastPrimitives.Close>
|
|
86
|
-
))
|
|
87
|
-
ToastClose.displayName = ToastPrimitives.Close.displayName
|
|
88
|
-
|
|
89
|
-
const ToastTitle = React.forwardRef<
|
|
90
|
-
React.ElementRef<typeof ToastPrimitives.Title>,
|
|
91
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>
|
|
92
|
-
>(({ className, ...props }, ref) => (
|
|
93
|
-
<ToastPrimitives.Title
|
|
94
|
-
ref={ref}
|
|
95
|
-
className={cn('text-sm font-semibold', className)}
|
|
96
|
-
{...props}
|
|
97
|
-
/>
|
|
98
|
-
))
|
|
99
|
-
ToastTitle.displayName = ToastPrimitives.Title.displayName
|
|
100
|
-
|
|
101
|
-
const ToastDescription = React.forwardRef<
|
|
102
|
-
React.ElementRef<typeof ToastPrimitives.Description>,
|
|
103
|
-
React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>
|
|
104
|
-
>(({ className, ...props }, ref) => (
|
|
105
|
-
<ToastPrimitives.Description
|
|
106
|
-
ref={ref}
|
|
107
|
-
className={cn('text-sm opacity-90', className)}
|
|
108
|
-
{...props}
|
|
109
|
-
/>
|
|
110
|
-
))
|
|
111
|
-
ToastDescription.displayName = ToastPrimitives.Description.displayName
|
|
112
|
-
|
|
113
|
-
type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>
|
|
114
|
-
|
|
115
|
-
type ToastActionElement = React.ReactElement<typeof ToastAction>
|
|
116
|
-
|
|
117
|
-
export {
|
|
118
|
-
Toast,
|
|
119
|
-
ToastAction,
|
|
120
|
-
ToastClose,
|
|
121
|
-
ToastDescription,
|
|
122
|
-
ToastProvider,
|
|
123
|
-
ToastTitle,
|
|
124
|
-
ToastViewport,
|
|
125
|
-
type ToastActionElement,
|
|
126
|
-
type ToastProps
|
|
127
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
Toast,
|
|
5
|
-
ToastClose,
|
|
6
|
-
ToastDescription,
|
|
7
|
-
ToastProvider,
|
|
8
|
-
ToastTitle,
|
|
9
|
-
ToastViewport
|
|
10
|
-
} from '@/components/ui/toast'
|
|
11
|
-
import { useToast } from '@/components/ui/use-toast'
|
|
12
|
-
|
|
13
|
-
export function Toaster() {
|
|
14
|
-
const { toasts } = useToast()
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<ToastProvider>
|
|
18
|
-
{toasts.map(function ({ id, title, description, action, ...props }) {
|
|
19
|
-
return (
|
|
20
|
-
<Toast key={id} {...props}>
|
|
21
|
-
<div className="grid gap-1">
|
|
22
|
-
{title && <ToastTitle>{title}</ToastTitle>}
|
|
23
|
-
{description && (
|
|
24
|
-
<ToastDescription>{description}</ToastDescription>
|
|
25
|
-
)}
|
|
26
|
-
</div>
|
|
27
|
-
{action}
|
|
28
|
-
<ToastClose />
|
|
29
|
-
</Toast>
|
|
30
|
-
)
|
|
31
|
-
})}
|
|
32
|
-
<ToastViewport />
|
|
33
|
-
</ToastProvider>
|
|
34
|
-
)
|
|
35
|
-
}
|
|
@@ -1,189 +0,0 @@
|
|
|
1
|
-
// Inspired by react-hot-toast library
|
|
2
|
-
import * as React from 'react'
|
|
3
|
-
|
|
4
|
-
import type { ToastActionElement, ToastProps } from '@/components/ui/toast'
|
|
5
|
-
|
|
6
|
-
const TOAST_LIMIT = 1
|
|
7
|
-
const TOAST_REMOVE_DELAY = 1000000
|
|
8
|
-
|
|
9
|
-
type ToasterToast = ToastProps & {
|
|
10
|
-
id: string
|
|
11
|
-
title?: React.ReactNode
|
|
12
|
-
description?: React.ReactNode
|
|
13
|
-
action?: ToastActionElement
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const actionTypes = {
|
|
17
|
-
ADD_TOAST: 'ADD_TOAST',
|
|
18
|
-
UPDATE_TOAST: 'UPDATE_TOAST',
|
|
19
|
-
DISMISS_TOAST: 'DISMISS_TOAST',
|
|
20
|
-
REMOVE_TOAST: 'REMOVE_TOAST'
|
|
21
|
-
} as const
|
|
22
|
-
|
|
23
|
-
let count = 0
|
|
24
|
-
|
|
25
|
-
function genId() {
|
|
26
|
-
count = (count + 1) % Number.MAX_VALUE
|
|
27
|
-
return count.toString()
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
type ActionType = typeof actionTypes
|
|
31
|
-
|
|
32
|
-
type Action =
|
|
33
|
-
| {
|
|
34
|
-
type: ActionType['ADD_TOAST']
|
|
35
|
-
toast: ToasterToast
|
|
36
|
-
}
|
|
37
|
-
| {
|
|
38
|
-
type: ActionType['UPDATE_TOAST']
|
|
39
|
-
toast: Partial<ToasterToast>
|
|
40
|
-
}
|
|
41
|
-
| {
|
|
42
|
-
type: ActionType['DISMISS_TOAST']
|
|
43
|
-
toastId?: ToasterToast['id']
|
|
44
|
-
}
|
|
45
|
-
| {
|
|
46
|
-
type: ActionType['REMOVE_TOAST']
|
|
47
|
-
toastId?: ToasterToast['id']
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
interface State {
|
|
51
|
-
toasts: ToasterToast[]
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
|
|
55
|
-
|
|
56
|
-
const addToRemoveQueue = (toastId: string) => {
|
|
57
|
-
if (toastTimeouts.has(toastId)) {
|
|
58
|
-
return
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const timeout = setTimeout(() => {
|
|
62
|
-
toastTimeouts.delete(toastId)
|
|
63
|
-
dispatch({
|
|
64
|
-
type: 'REMOVE_TOAST',
|
|
65
|
-
toastId: toastId
|
|
66
|
-
})
|
|
67
|
-
}, TOAST_REMOVE_DELAY)
|
|
68
|
-
|
|
69
|
-
toastTimeouts.set(toastId, timeout)
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
export const reducer = (state: State, action: Action): State => {
|
|
73
|
-
switch (action.type) {
|
|
74
|
-
case 'ADD_TOAST':
|
|
75
|
-
return {
|
|
76
|
-
...state,
|
|
77
|
-
toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
case 'UPDATE_TOAST':
|
|
81
|
-
return {
|
|
82
|
-
...state,
|
|
83
|
-
toasts: state.toasts.map(t =>
|
|
84
|
-
t.id === action.toast.id ? { ...t, ...action.toast } : t
|
|
85
|
-
)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
case 'DISMISS_TOAST': {
|
|
89
|
-
const { toastId } = action
|
|
90
|
-
|
|
91
|
-
// ! Side effects ! - This could be extracted into a dismissToast() action,
|
|
92
|
-
// but I'll keep it here for simplicity
|
|
93
|
-
if (toastId) {
|
|
94
|
-
addToRemoveQueue(toastId)
|
|
95
|
-
} else {
|
|
96
|
-
state.toasts.forEach(toast => {
|
|
97
|
-
addToRemoveQueue(toast.id)
|
|
98
|
-
})
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return {
|
|
102
|
-
...state,
|
|
103
|
-
toasts: state.toasts.map(t =>
|
|
104
|
-
t.id === toastId || toastId === undefined
|
|
105
|
-
? {
|
|
106
|
-
...t,
|
|
107
|
-
open: false
|
|
108
|
-
}
|
|
109
|
-
: t
|
|
110
|
-
)
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
case 'REMOVE_TOAST':
|
|
114
|
-
if (action.toastId === undefined) {
|
|
115
|
-
return {
|
|
116
|
-
...state,
|
|
117
|
-
toasts: []
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
return {
|
|
121
|
-
...state,
|
|
122
|
-
toasts: state.toasts.filter(t => t.id !== action.toastId)
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const listeners: Array<(state: State) => void> = []
|
|
128
|
-
|
|
129
|
-
let memoryState: State = { toasts: [] }
|
|
130
|
-
|
|
131
|
-
function dispatch(action: Action) {
|
|
132
|
-
memoryState = reducer(memoryState, action)
|
|
133
|
-
listeners.forEach(listener => {
|
|
134
|
-
listener(memoryState)
|
|
135
|
-
})
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
type Toast = Omit<ToasterToast, 'id'>
|
|
139
|
-
|
|
140
|
-
function toast({ ...props }: Toast) {
|
|
141
|
-
const id = genId()
|
|
142
|
-
|
|
143
|
-
const update = (props: ToasterToast) =>
|
|
144
|
-
dispatch({
|
|
145
|
-
type: 'UPDATE_TOAST',
|
|
146
|
-
toast: { ...props, id }
|
|
147
|
-
})
|
|
148
|
-
const dismiss = () => dispatch({ type: 'DISMISS_TOAST', toastId: id })
|
|
149
|
-
|
|
150
|
-
dispatch({
|
|
151
|
-
type: 'ADD_TOAST',
|
|
152
|
-
toast: {
|
|
153
|
-
...props,
|
|
154
|
-
id,
|
|
155
|
-
open: true,
|
|
156
|
-
onOpenChange: open => {
|
|
157
|
-
if (!open) dismiss()
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
})
|
|
161
|
-
|
|
162
|
-
return {
|
|
163
|
-
id: id,
|
|
164
|
-
dismiss,
|
|
165
|
-
update
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
function useToast() {
|
|
170
|
-
const [state, setState] = React.useState<State>(memoryState)
|
|
171
|
-
|
|
172
|
-
React.useEffect(() => {
|
|
173
|
-
listeners.push(setState)
|
|
174
|
-
return () => {
|
|
175
|
-
const index = listeners.indexOf(setState)
|
|
176
|
-
if (index > -1) {
|
|
177
|
-
listeners.splice(index, 1)
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
}, [state])
|
|
181
|
-
|
|
182
|
-
return {
|
|
183
|
-
...state,
|
|
184
|
-
toast,
|
|
185
|
-
dismiss: (toastId?: string) => dispatch({ type: 'DISMISS_TOAST', toastId })
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
export { toast, useToast }
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { User } from 'next-auth'
|
|
4
|
-
import { signOut } from 'next-auth/react'
|
|
5
|
-
import Link from 'next/link'
|
|
6
|
-
import { FC, HTMLAttributes } from 'react'
|
|
7
|
-
|
|
8
|
-
import {
|
|
9
|
-
DropdownMenu,
|
|
10
|
-
DropdownMenuContent,
|
|
11
|
-
DropdownMenuItem,
|
|
12
|
-
DropdownMenuSeparator,
|
|
13
|
-
DropdownMenuTrigger
|
|
14
|
-
} from '@/components/ui/dropdown-menu'
|
|
15
|
-
import { UserAvatar } from '@/components/user-avatar'
|
|
16
|
-
|
|
17
|
-
interface UserAccountNavProps extends HTMLAttributes<HTMLDivElement> {
|
|
18
|
-
user: Pick<User, 'name' | 'image' | 'email'>
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export const UserAccountNav: FC<UserAccountNavProps> = ({ user }) => {
|
|
22
|
-
return (
|
|
23
|
-
<DropdownMenu>
|
|
24
|
-
<DropdownMenuTrigger>
|
|
25
|
-
<UserAvatar
|
|
26
|
-
user={{ name: user.name || null, image: user.image || null }}
|
|
27
|
-
className="h-8 w-8"
|
|
28
|
-
/>
|
|
29
|
-
</DropdownMenuTrigger>
|
|
30
|
-
<DropdownMenuContent align="end">
|
|
31
|
-
<div className="flex items-center justify-start gap-2 p-2">
|
|
32
|
-
<div className="flex flex-col space-y-1 leading-none">
|
|
33
|
-
{user.name && <p className="font-medium">{user.name}</p>}
|
|
34
|
-
{user.email && (
|
|
35
|
-
<p className="w-[200px] truncate text-sm text-muted-foreground">
|
|
36
|
-
{user.email}
|
|
37
|
-
</p>
|
|
38
|
-
)}
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
<DropdownMenuSeparator />
|
|
42
|
-
<DropdownMenuItem asChild>
|
|
43
|
-
<Link href="/settings">Settings</Link>
|
|
44
|
-
</DropdownMenuItem>
|
|
45
|
-
<DropdownMenuSeparator />
|
|
46
|
-
<DropdownMenuItem
|
|
47
|
-
className="cursor-pointer"
|
|
48
|
-
onSelect={event => {
|
|
49
|
-
event.preventDefault()
|
|
50
|
-
signOut({
|
|
51
|
-
callbackUrl: `${window.location.origin}/login`
|
|
52
|
-
})
|
|
53
|
-
}}
|
|
54
|
-
>
|
|
55
|
-
Sign out
|
|
56
|
-
</DropdownMenuItem>
|
|
57
|
-
</DropdownMenuContent>
|
|
58
|
-
</DropdownMenu>
|
|
59
|
-
)
|
|
60
|
-
}
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import { User } from '@prisma/client'
|
|
2
|
-
import { AvatarProps } from '@radix-ui/react-avatar'
|
|
3
|
-
import { FC } from 'react'
|
|
4
|
-
|
|
5
|
-
import { Icons } from '@/components/icons'
|
|
6
|
-
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar'
|
|
7
|
-
|
|
8
|
-
interface UserAvatarProps extends AvatarProps {
|
|
9
|
-
user: Pick<User, 'image' | 'name'>
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
export const UserAvatar: FC<UserAvatarProps> = ({ user, ...props }) => {
|
|
13
|
-
return (
|
|
14
|
-
<Avatar {...props}>
|
|
15
|
-
{user.image ? (
|
|
16
|
-
<AvatarImage alt="Picture" src={user.image} />
|
|
17
|
-
) : (
|
|
18
|
-
<AvatarFallback>
|
|
19
|
-
<span className="sr-only">{user.name}</span>
|
|
20
|
-
<Icons.user className="h-4 w-4" />
|
|
21
|
-
</AvatarFallback>
|
|
22
|
-
)}
|
|
23
|
-
</Avatar>
|
|
24
|
-
)
|
|
25
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { createEnv } from '@t3-oss/env-nextjs'
|
|
2
|
-
import { z } from 'zod'
|
|
3
|
-
|
|
4
|
-
export const env = createEnv({
|
|
5
|
-
/**
|
|
6
|
-
* Specify your server-side environment variables schema here. This way you can ensure the app
|
|
7
|
-
* isn't built with invalid env vars.
|
|
8
|
-
*/
|
|
9
|
-
server: {
|
|
10
|
-
NODE_ENV: z.enum(['development', 'test', 'production']),
|
|
11
|
-
DATABASE_URL: z.string().url(),
|
|
12
|
-
NEXTAUTH_SECRET:
|
|
13
|
-
process.env.NODE_ENV === 'production'
|
|
14
|
-
? z.string().min(1)
|
|
15
|
-
: z.string().min(1).optional(),
|
|
16
|
-
NEXTAUTH_URL: z.preprocess(
|
|
17
|
-
// This makes Vercel deployments not fail if you don't set NEXTAUTH_URL
|
|
18
|
-
// Since NextAuth.js automatically uses the VERCEL_URL if present.
|
|
19
|
-
str => process.env.VERCEL_URL ?? str,
|
|
20
|
-
// VERCEL_URL doesn't include `https` so it cant be validated as a URL
|
|
21
|
-
process.env.VERCEL ? z.string().min(1) : z.string().url()
|
|
22
|
-
),
|
|
23
|
-
EMAIL_SERVER_HOST: z.string().min(1),
|
|
24
|
-
EMAIL_SERVER_PORT: z.number(),
|
|
25
|
-
EMAIL_SERVER_USER: z.string().min(1),
|
|
26
|
-
EMAIL_SERVER_PASSWORD: z.string().min(1),
|
|
27
|
-
EMAIL_FROM: z.string().email(),
|
|
28
|
-
GOOGLE_ID: z.string().min(1),
|
|
29
|
-
GOOGLE_SECRET: z.string().min(1),
|
|
30
|
-
GITHUB_ID: z.string().min(1),
|
|
31
|
-
GITHUB_SECRET: z.string().min(1),
|
|
32
|
-
FIREBASE_PROJECT_ID: z.string().min(1),
|
|
33
|
-
FIREBASE_PRIVATE_KEY: z.string().min(1),
|
|
34
|
-
FIREBASE_CLIENT_EMAIL: z.string().min(1),
|
|
35
|
-
FIREBASE_STORAGE_BUCKET: z.string().min(1)
|
|
36
|
-
},
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Specify your client-side environment variables schema here. This way you can ensure the app
|
|
40
|
-
* isn't built with invalid env vars. To expose them to the client, prefix them with
|
|
41
|
-
* `NEXT_PUBLIC_`.
|
|
42
|
-
*/
|
|
43
|
-
client: {
|
|
44
|
-
// NEXT_PUBLIC_CLIENTVAR: z.string().min(1),
|
|
45
|
-
},
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* You can't destruct `process.env` as a regular object in the Next.js edge runtimes (e.g.
|
|
49
|
-
* middlewares) or client-side so we need to destruct manually.
|
|
50
|
-
*/
|
|
51
|
-
runtimeEnv: {
|
|
52
|
-
NODE_ENV: process.env.NODE_ENV,
|
|
53
|
-
DATABASE_URL: process.env.DATABASE_URL,
|
|
54
|
-
NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET,
|
|
55
|
-
NEXTAUTH_URL: process.env.NEXTAUTH_URL,
|
|
56
|
-
EMAIL_SERVER_HOST: process.env.EMAIL_SERVER_HOST,
|
|
57
|
-
EMAIL_SERVER_PORT: parseInt(process.env.EMAIL_SERVER_PORT || ''),
|
|
58
|
-
EMAIL_SERVER_USER: process.env.EMAIL_SERVER_USER,
|
|
59
|
-
EMAIL_SERVER_PASSWORD: process.env.EMAIL_SERVER_PASSWORD,
|
|
60
|
-
EMAIL_FROM: process.env.EMAIL_FROM,
|
|
61
|
-
GOOGLE_ID: process.env.GOOGLE_ID,
|
|
62
|
-
GOOGLE_SECRET: process.env.GOOGLE_SECRET,
|
|
63
|
-
GITHUB_ID: process.env.GITHUB_ID,
|
|
64
|
-
GITHUB_SECRET: process.env.GITHUB_SECRET,
|
|
65
|
-
FIREBASE_PROJECT_ID: process.env.FIREBASE_PROJECT_ID,
|
|
66
|
-
FIREBASE_PRIVATE_KEY: process.env.FIREBASE_PRIVATE_KEY,
|
|
67
|
-
FIREBASE_CLIENT_EMAIL: process.env.FIREBASE_CLIENT_EMAIL,
|
|
68
|
-
FIREBASE_STORAGE_BUCKET: process.env.FIREBASE_STORAGE_BUCKET
|
|
69
|
-
},
|
|
70
|
-
/**
|
|
71
|
-
* Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation.
|
|
72
|
-
* This is especially useful for Docker builds.
|
|
73
|
-
*/
|
|
74
|
-
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
|
|
75
|
-
|
|
76
|
-
// This makes empty strings be treated as undefined
|
|
77
|
-
emptyStringAsUndefined: true
|
|
78
|
-
})
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
'use client'
|
|
2
|
-
|
|
3
|
-
import { useEffect, useState } from 'react'
|
|
4
|
-
|
|
5
|
-
export function useDebounce<T>(value: T, delay?: number): T {
|
|
6
|
-
const [debouncedValue, setDebouncedValue] = useState<T>(value)
|
|
7
|
-
|
|
8
|
-
useEffect(() => {
|
|
9
|
-
const timer = setTimeout(() => setDebouncedValue(value), delay || 500)
|
|
10
|
-
|
|
11
|
-
return () => {
|
|
12
|
-
clearTimeout(timer)
|
|
13
|
-
}
|
|
14
|
-
}, [value, delay])
|
|
15
|
-
|
|
16
|
-
return debouncedValue
|
|
17
|
-
}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { useLayoutEffect } from 'react'
|
|
2
|
-
|
|
3
|
-
// @see https://usehooks.com/useLockBodyScroll.
|
|
4
|
-
export function useLockBody() {
|
|
5
|
-
useLayoutEffect((): (() => void) => {
|
|
6
|
-
const originalStyle: string = window.getComputedStyle(
|
|
7
|
-
document.body
|
|
8
|
-
).overflow
|
|
9
|
-
document.body.style.overflow = 'hidden'
|
|
10
|
-
return () => (document.body.style.overflow = originalStyle)
|
|
11
|
-
}, [])
|
|
12
|
-
}
|