create-apppaaaul 2.0.15 → 2.0.17
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/dist/index.js +2 -4
- package/dist/index.js.map +1 -1
- package/dist/templates/nextjs-ts-clean/project/%%.gitignore +43 -0
- package/dist/templates/nextjs-ts-clean/project/eslint.config.mjs +137 -114
- package/dist/templates/nextjs-ts-clean/project/package.json +15 -15
- package/dist/templates/nextjs-ts-clean/project/src/scripts/dev-rebase.js +12 -2
- package/dist/templates/nextjs-ts-landing-prisma/project/%%.gitignore +46 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/.env.test +26 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/eslint.config.mjs +137 -114
- package/dist/templates/nextjs-ts-landing-prisma/project/package.json +34 -26
- package/dist/templates/nextjs-ts-landing-prisma/project/prisma/schema.prisma +74 -14
- package/dist/templates/nextjs-ts-landing-prisma/project/src/app/api/auth/[...all]/route.ts +5 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/src/app/not-found.tsx +118 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/src/lib/auth-client.ts +9 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/src/lib/auth-utils.ts +197 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/src/lib/auth.ts +49 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/src/lib/cloudflare-r2.ts +124 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/src/lib/db.ts +24 -5
- package/dist/templates/nextjs-ts-landing-prisma/project/src/lib/env.ts +44 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/src/middleware.ts +105 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/src/scripts/db-seed.ts +16 -0
- package/dist/templates/nextjs-ts-landing-prisma/project/src/scripts/dev-rebase.js +12 -2
- package/package.json +1 -1
- package/dist/templates/nextjs-ts-landing-drizzle/project/README.md +0 -15
- package/dist/templates/nextjs-ts-landing-drizzle/project/components.json +0 -21
- package/dist/templates/nextjs-ts-landing-drizzle/project/drizzle.config.ts +0 -11
- package/dist/templates/nextjs-ts-landing-drizzle/project/eslint.config.mjs +0 -183
- package/dist/templates/nextjs-ts-landing-drizzle/project/next.config.mjs +0 -10
- package/dist/templates/nextjs-ts-landing-drizzle/project/package.json +0 -61
- package/dist/templates/nextjs-ts-landing-drizzle/project/postcss.config.js +0 -3
- package/dist/templates/nextjs-ts-landing-drizzle/project/public/next.svg +0 -1
- package/dist/templates/nextjs-ts-landing-drizzle/project/public/vercel.svg +0 -1
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/app/api/auth/[...nextauth]/route.ts +0 -3
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/app/favicon.ico +0 -0
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/app/globals.css +0 -161
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/app/layout.tsx +0 -25
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/app/page.tsx +0 -5
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/auth.ts +0 -79
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/components/ui/button.tsx +0 -49
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/db/index.ts +0 -25
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/db/schema.ts +0 -93
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/lib/utils.ts +0 -6
- package/dist/templates/nextjs-ts-landing-drizzle/project/src/scripts/dev-rebase.js +0 -32
- package/dist/templates/nextjs-ts-landing-drizzle/project/tailwind.config.ts +0 -80
- package/dist/templates/nextjs-ts-landing-drizzle/project/tsconfig.json +0 -27
- package/dist/templates/nextjs-ts-landing-prisma/project/src/app/api/auth/[...nextauth]/route.ts +0 -3
- package/dist/templates/nextjs-ts-landing-prisma/project/src/auth.ts +0 -31
|
@@ -1,67 +1,90 @@
|
|
|
1
|
-
import
|
|
1
|
+
import { FlatCompat } from "@eslint/eslintrc";
|
|
2
|
+
import { defineConfig } from "eslint/config";
|
|
2
3
|
import tseslint from "typescript-eslint";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import eslintPluginPrettier from "eslint-plugin-prettier/recommended";
|
|
4
|
+
import eslintJs from "@eslint/js";
|
|
5
|
+
import eslintReact from "@eslint-react/eslint-plugin";
|
|
6
|
+
import eslintPluginPrettierRecommended from "eslint-plugin-prettier/recommended";
|
|
7
7
|
import eslintPluginImport from "eslint-plugin-import";
|
|
8
8
|
import eslintPluginReactCompiler from "eslint-plugin-react-compiler";
|
|
9
|
-
import eslintPluginNext from "@next/eslint-plugin-next";
|
|
10
9
|
import eslintPluginJsxA11y from "eslint-plugin-jsx-a11y";
|
|
10
|
+
import eslintPluginReact from "eslint-plugin-react";
|
|
11
|
+
import eslintPluginStylistic from "@stylistic/eslint-plugin";
|
|
11
12
|
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
const compat = new FlatCompat({
|
|
14
|
+
baseDirectory: import.meta.dirname,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const languageLintingConfig = tseslint.config(
|
|
14
18
|
{
|
|
15
|
-
|
|
19
|
+
files: ["**/*.{ts,tsx,js,mjs,cjs}"],
|
|
20
|
+
languageOptions: {
|
|
21
|
+
parser: tseslint.parser,
|
|
22
|
+
parserOptions: {
|
|
23
|
+
projectService: {
|
|
24
|
+
allowDefaultProject: ["*.js", "*.mjs", "*.cjs"],
|
|
25
|
+
},
|
|
26
|
+
tsconfigRootDir: import.meta.dirname,
|
|
27
|
+
},
|
|
28
|
+
},
|
|
16
29
|
},
|
|
17
|
-
|
|
30
|
+
eslintJs.configs.recommended,
|
|
31
|
+
tseslint.configs.strictTypeChecked,
|
|
32
|
+
tseslint.configs.stylisticTypeChecked,
|
|
33
|
+
eslintPluginStylistic.configs.recommended,
|
|
18
34
|
{
|
|
19
35
|
rules: {
|
|
20
|
-
"
|
|
36
|
+
"no-console": ["warn", { allow: ["error"] }],
|
|
37
|
+
"@stylistic/padding-line-between-statements": [
|
|
21
38
|
"warn",
|
|
22
|
-
{blankLine: "always", prev: "*", next: ["return", "export"]},
|
|
23
|
-
{blankLine: "always", prev: ["const", "let", "var"], next: "*"},
|
|
24
|
-
{
|
|
39
|
+
{ blankLine: "always", prev: "*", next: ["return", "export"] },
|
|
40
|
+
{ blankLine: "always", prev: ["const", "let", "var"], next: "*" },
|
|
41
|
+
{
|
|
42
|
+
blankLine: "any",
|
|
43
|
+
prev: ["const", "let", "var"],
|
|
44
|
+
next: ["const", "let", "var"],
|
|
45
|
+
},
|
|
25
46
|
],
|
|
26
|
-
"no-
|
|
47
|
+
"@typescript-eslint/no-unused-vars": [
|
|
48
|
+
"warn",
|
|
49
|
+
{
|
|
50
|
+
args: "after-used",
|
|
51
|
+
ignoreRestSiblings: false,
|
|
52
|
+
argsIgnorePattern: "^_.*?$",
|
|
53
|
+
caughtErrorsIgnorePattern: "^_.*?$",
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
"@typescript-eslint/no-unsafe-member-access": "off",
|
|
57
|
+
"@typescript-eslint/no-confusing-void-expression": "off",
|
|
58
|
+
"@typescript-eslint/ban-ts-comment": "off",
|
|
59
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
60
|
+
"@typescript-eslint/no-inferrable-types": "off",
|
|
61
|
+
// Optionals
|
|
62
|
+
// "@typescript-eslint/no-floating-promises": "off",
|
|
63
|
+
// "@typescript-eslint/no-non-null-assertion": "off",
|
|
27
64
|
},
|
|
28
65
|
},
|
|
29
|
-
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
const reactLintingConfig = defineConfig([
|
|
30
69
|
{
|
|
31
|
-
|
|
32
|
-
react: fixupPluginRules(eslintPluginReact),
|
|
33
|
-
"react-hooks": fixupPluginRules(eslintPluginReactHooks),
|
|
34
|
-
"react-compiler": fixupPluginRules(eslintPluginReactCompiler),
|
|
35
|
-
"jsx-a11y": fixupPluginRules(eslintPluginJsxA11y),
|
|
36
|
-
},
|
|
37
|
-
languageOptions: {
|
|
38
|
-
parserOptions: {
|
|
39
|
-
ecmaFeatures: {
|
|
40
|
-
jsx: true,
|
|
41
|
-
},
|
|
42
|
-
},
|
|
43
|
-
globals: {
|
|
44
|
-
...globals.browser,
|
|
45
|
-
...globals.serviceworker,
|
|
46
|
-
},
|
|
47
|
-
},
|
|
70
|
+
files: ["**/*.{tsx,jsx}"],
|
|
48
71
|
settings: {
|
|
49
72
|
react: {
|
|
50
73
|
version: "detect",
|
|
51
74
|
},
|
|
52
75
|
},
|
|
76
|
+
},
|
|
77
|
+
eslintPluginReact.configs.flat.recommended,
|
|
78
|
+
eslintPluginReact.configs.flat["jsx-runtime"],
|
|
79
|
+
eslintReact.configs["recommended-type-checked"],
|
|
80
|
+
eslintPluginReactCompiler.configs.recommended,
|
|
81
|
+
{
|
|
53
82
|
rules: {
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
...eslintPluginReactHooks.configs.recommended.rules,
|
|
57
|
-
"react/jsx-boolean-value": ["error", "never"],
|
|
58
|
-
"react/jsx-curly-brace-presence": ["error", {props: "never", children: "never"}],
|
|
59
|
-
"react/jsx-no-useless-fragment": "error",
|
|
60
|
-
"react/prop-types": "off",
|
|
61
|
-
"react/jsx-uses-react": "off",
|
|
83
|
+
"@eslint-react/no-useless-fragment": "error",
|
|
84
|
+
"@eslint-react/no-missing-key": "warn",
|
|
62
85
|
"react/no-array-index-key": "off",
|
|
63
|
-
"react/react-in-jsx-scope": "off",
|
|
64
86
|
"react/self-closing-comp": "warn",
|
|
87
|
+
"react/jsx-curly-brace-presence": ["error", { props: "never", children: "never" }],
|
|
65
88
|
"react/jsx-sort-props": [
|
|
66
89
|
"warn",
|
|
67
90
|
{
|
|
@@ -71,73 +94,56 @@ export default [
|
|
|
71
94
|
reservedFirst: true,
|
|
72
95
|
},
|
|
73
96
|
],
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
]);
|
|
100
|
+
|
|
101
|
+
const reactA11yLintingConfig = defineConfig([
|
|
102
|
+
{
|
|
103
|
+
files: ["**/*.{tsx,jsx}"],
|
|
104
|
+
},
|
|
105
|
+
eslintPluginJsxA11y.flatConfigs.recommended,
|
|
106
|
+
{
|
|
107
|
+
rules: {
|
|
77
108
|
"jsx-a11y/click-events-have-key-events": "off",
|
|
78
|
-
"jsx-a11y/html-has-lang": "off",
|
|
79
109
|
},
|
|
80
110
|
},
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
"@typescript-eslint/no-explicit-any": "off",
|
|
92
|
-
"@typescript-eslint/no-inferrable-types": "off",
|
|
93
|
-
"@typescript-eslint/no-namespace": "off",
|
|
94
|
-
"@typescript-eslint/no-non-null-assertion": "off",
|
|
95
|
-
"@typescript-eslint/no-shadow": "off",
|
|
96
|
-
"@typescript-eslint/explicit-function-return-type": "off",
|
|
97
|
-
"@typescript-eslint/require-await": "off",
|
|
98
|
-
"@typescript-eslint/no-floating-promises": "off",
|
|
99
|
-
"@typescript-eslint/no-confusing-void-expression": "off",
|
|
100
|
-
"@typescript-eslint/no-unused-vars": [
|
|
101
|
-
"warn",
|
|
102
|
-
{
|
|
103
|
-
args: "after-used",
|
|
104
|
-
ignoreRestSiblings: false,
|
|
105
|
-
argsIgnorePattern: "^_.*?$",
|
|
106
|
-
caughtErrorsIgnorePattern: "^_.*?$",
|
|
107
|
-
},
|
|
108
|
-
],
|
|
109
|
-
},
|
|
111
|
+
]);
|
|
112
|
+
|
|
113
|
+
const nextLintingConfig = defineConfig([
|
|
114
|
+
{
|
|
115
|
+
files: ["**/*.{tsx,jsx}"],
|
|
116
|
+
},
|
|
117
|
+
compat.extends("plugin:@next/next/recommended"),
|
|
118
|
+
{
|
|
119
|
+
rules: {
|
|
120
|
+
"@next/next/no-img-element": "off",
|
|
110
121
|
},
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
semi: true,
|
|
124
|
-
singleQuote: false,
|
|
125
|
-
bracketSpacing: true,
|
|
126
|
-
arrowParens: "always",
|
|
127
|
-
endOfLine: "auto",
|
|
128
|
-
plugins: ["prettier-plugin-tailwindcss"],
|
|
129
|
-
},
|
|
130
|
-
],
|
|
122
|
+
},
|
|
123
|
+
]);
|
|
124
|
+
|
|
125
|
+
const importLintingConfig = defineConfig([
|
|
126
|
+
{
|
|
127
|
+
files: ["**/*.{ts,tsx,js,mjs,cjs}"],
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
settings: {
|
|
131
|
+
"import/resolver": {
|
|
132
|
+
typescript: true,
|
|
133
|
+
node: true,
|
|
131
134
|
},
|
|
132
135
|
},
|
|
133
|
-
|
|
134
|
-
|
|
136
|
+
},
|
|
137
|
+
eslintPluginImport.flatConfigs.recommended,
|
|
138
|
+
eslintPluginImport.flatConfigs.typescript,
|
|
135
139
|
{
|
|
136
|
-
plugins: {
|
|
137
|
-
import: fixupPluginRules(eslintPluginImport),
|
|
138
|
-
},
|
|
139
140
|
rules: {
|
|
140
141
|
"import/no-default-export": "off",
|
|
142
|
+
"import/no-named-as-default-member": "off",
|
|
143
|
+
"import/named": "off",
|
|
144
|
+
"import/namespace": "off",
|
|
145
|
+
"import/default": "off",
|
|
146
|
+
"import/no-unresolved": "off",
|
|
141
147
|
"import/order": [
|
|
142
148
|
"warn",
|
|
143
149
|
{
|
|
@@ -163,21 +169,38 @@ export default [
|
|
|
163
169
|
],
|
|
164
170
|
},
|
|
165
171
|
},
|
|
166
|
-
|
|
172
|
+
]);
|
|
173
|
+
|
|
174
|
+
const prettierLintingConfig = defineConfig([
|
|
175
|
+
{
|
|
176
|
+
files: ["**/*.{ts,tsx,js,mjs,cjs}"],
|
|
177
|
+
},
|
|
178
|
+
eslintPluginPrettierRecommended,
|
|
167
179
|
{
|
|
168
|
-
plugins: {
|
|
169
|
-
"@next/next": fixupPluginRules(eslintPluginNext),
|
|
170
|
-
},
|
|
171
|
-
languageOptions: {
|
|
172
|
-
globals: {
|
|
173
|
-
...globals.node,
|
|
174
|
-
...globals.browser,
|
|
175
|
-
},
|
|
176
|
-
},
|
|
177
180
|
rules: {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
+
"prettier/prettier": [
|
|
182
|
+
"warn",
|
|
183
|
+
{
|
|
184
|
+
printWidth: 100,
|
|
185
|
+
trailingComma: "all",
|
|
186
|
+
tabWidth: 2,
|
|
187
|
+
semi: true,
|
|
188
|
+
singleQuote: false,
|
|
189
|
+
bracketSpacing: true,
|
|
190
|
+
arrowParens: "always",
|
|
191
|
+
endOfLine: "auto",
|
|
192
|
+
plugins: ["prettier-plugin-tailwindcss"],
|
|
193
|
+
},
|
|
194
|
+
],
|
|
181
195
|
},
|
|
182
196
|
},
|
|
183
|
-
];
|
|
197
|
+
]);
|
|
198
|
+
|
|
199
|
+
export default defineConfig([
|
|
200
|
+
languageLintingConfig,
|
|
201
|
+
reactLintingConfig,
|
|
202
|
+
reactA11yLintingConfig,
|
|
203
|
+
nextLintingConfig,
|
|
204
|
+
importLintingConfig,
|
|
205
|
+
prettierLintingConfig,
|
|
206
|
+
]);
|
|
@@ -6,56 +6,64 @@
|
|
|
6
6
|
"dev": "next dev --turbopack",
|
|
7
7
|
"build": "next build",
|
|
8
8
|
"start": "next start",
|
|
9
|
+
"postinstall": "npx prisma generate",
|
|
9
10
|
"lint": "next lint",
|
|
10
11
|
"db:push": "npx prisma generate &&npx prisma db push",
|
|
11
|
-
"
|
|
12
|
+
"db:seed": "tsx src/scripts/db-seed.ts",
|
|
13
|
+
"db:studio": "npx prisma studio",
|
|
14
|
+
"prod": "pnpm build && git checkout main && git pull origin main && git merge dev && pnpm version patch && git push origin main && git checkout dev && echo ✅ Deploy completado",
|
|
12
15
|
"dev-rebase": "node src/scripts/dev-rebase.js"
|
|
13
|
-
|
|
16
|
+
},
|
|
14
17
|
"dependencies": {
|
|
15
|
-
"@auth/prisma-adapter": "^2.
|
|
16
|
-
"@
|
|
18
|
+
"@auth/prisma-adapter": "^2.11.0",
|
|
19
|
+
"@aws-sdk/client-s3": "^3.916.0",
|
|
20
|
+
"@aws-sdk/s3-request-presigner": "^3.916.0",
|
|
21
|
+
"@prisma/client": "^6.18.0",
|
|
17
22
|
"@radix-ui/react-slot": "^1.2.3",
|
|
18
|
-
"@
|
|
23
|
+
"@react-email/render": "^1.4.0",
|
|
24
|
+
"@tailwindcss/postcss": "^4.1.16",
|
|
19
25
|
"autoprefixer": "^10.4.21",
|
|
20
26
|
"bcryptjs": "^3.0.2",
|
|
27
|
+
"better-auth": "^1.3.29",
|
|
21
28
|
"class-variance-authority": "^0.7.1",
|
|
22
29
|
"clsx": "^2.1.1",
|
|
23
|
-
"dotenv": "^17.2.
|
|
24
|
-
"lucide-react": "^0.
|
|
25
|
-
"
|
|
26
|
-
"next
|
|
30
|
+
"dotenv": "^17.2.3",
|
|
31
|
+
"lucide-react": "^0.547.0",
|
|
32
|
+
"motion": "^12.23.24",
|
|
33
|
+
"next": "^16.0.0",
|
|
27
34
|
"postcss": "^8.5.6",
|
|
28
35
|
"postgres": "^3.4.7",
|
|
29
|
-
"react": "^19.
|
|
30
|
-
"react-dom": "^19.
|
|
36
|
+
"react": "^19.2.0",
|
|
37
|
+
"react-dom": "^19.2.0",
|
|
38
|
+
"resend": "^6.2.2",
|
|
31
39
|
"sonner": "^2.0.7",
|
|
32
40
|
"tailwind-merge": "^3.3.1",
|
|
33
|
-
"tailwindcss": "^4.1.
|
|
41
|
+
"tailwindcss": "^4.1.16",
|
|
34
42
|
"tailwindcss-animate": "^1.0.7",
|
|
35
|
-
"zod": "^4.1.
|
|
43
|
+
"zod": "^4.1.12"
|
|
36
44
|
},
|
|
37
45
|
"devDependencies": {
|
|
38
|
-
"@eslint/compat": "^1.
|
|
39
|
-
"@next/eslint-plugin-next": "
|
|
40
|
-
"@types/node": "^24.
|
|
41
|
-
"@types/react": "^19.
|
|
42
|
-
"@types/react-dom": "^19.
|
|
46
|
+
"@eslint/compat": "^1.4.0",
|
|
47
|
+
"@next/eslint-plugin-next": "16.0.0",
|
|
48
|
+
"@types/node": "^24.9.1",
|
|
49
|
+
"@types/react": "^19.2.2",
|
|
50
|
+
"@types/react-dom": "^19.2.2",
|
|
43
51
|
"babel-plugin-react-compiler": "19.0.0-beta-e1e972c-20250221",
|
|
44
|
-
"eslint": "^9.
|
|
45
|
-
"eslint-config-next": "^
|
|
52
|
+
"eslint": "^9.38.0",
|
|
53
|
+
"eslint-config-next": "^16.0.0",
|
|
46
54
|
"eslint-config-prettier": "^10.1.8",
|
|
47
55
|
"eslint-plugin-import": "^2.32.0",
|
|
48
56
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
49
57
|
"eslint-plugin-prettier": "^5.5.4",
|
|
50
58
|
"eslint-plugin-react": "^7.37.5",
|
|
51
59
|
"eslint-plugin-react-compiler": "0.0.0-experimental-c8b3f72-20240517",
|
|
52
|
-
"eslint-plugin-react-hooks": "^
|
|
60
|
+
"eslint-plugin-react-hooks": "^7.0.0",
|
|
53
61
|
"globals": "^16.4.0",
|
|
54
62
|
"prettier": "^3.6.2",
|
|
55
|
-
"prettier-plugin-tailwindcss": "^0.
|
|
56
|
-
"prisma": "^6.
|
|
57
|
-
"tsx": "^4.20.
|
|
58
|
-
"typescript": "^5.9.
|
|
59
|
-
"typescript-eslint": "^8.
|
|
63
|
+
"prettier-plugin-tailwindcss": "^0.7.1",
|
|
64
|
+
"prisma": "^6.18.0",
|
|
65
|
+
"tsx": "^4.20.6",
|
|
66
|
+
"typescript": "^5.9.3",
|
|
67
|
+
"typescript-eslint": "^8.46.2"
|
|
60
68
|
}
|
|
61
69
|
}
|
|
@@ -1,25 +1,85 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
|
|
2
|
+
generator client {
|
|
3
|
+
provider = "prisma-client-js"
|
|
4
4
|
}
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
provider = "
|
|
8
|
-
|
|
6
|
+
datasource db {
|
|
7
|
+
provider = "postgresql"
|
|
8
|
+
url = env("DATABASE_URL")
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
model Post {
|
|
11
|
+
model Post {
|
|
12
12
|
id Int @id @default(autoincrement())
|
|
13
13
|
title String
|
|
14
14
|
content String?
|
|
15
15
|
published Boolean @default(false)
|
|
16
16
|
author User? @relation(fields: [authorId], references: [id])
|
|
17
|
-
authorId Int?
|
|
17
|
+
authorId Int?
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
model User {
|
|
21
|
+
id Int @id @default(autoincrement())
|
|
22
|
+
email String @unique
|
|
23
|
+
name String?
|
|
24
|
+
posts Post[]
|
|
25
|
+
emailVerified Boolean @default(false)
|
|
26
|
+
image String?
|
|
27
|
+
createdAt DateTime @default(now())
|
|
28
|
+
updatedAt DateTime @default(now()) @updatedAt
|
|
29
|
+
role String
|
|
30
|
+
banned Boolean? @default(false)
|
|
31
|
+
banReason String?
|
|
32
|
+
banExpires DateTime?
|
|
33
|
+
lastName String?
|
|
34
|
+
username String?
|
|
35
|
+
sessions Session[]
|
|
36
|
+
accounts Account[]
|
|
37
|
+
|
|
38
|
+
@@map("user")
|
|
18
39
|
}
|
|
40
|
+
|
|
41
|
+
model Session {
|
|
42
|
+
id String @id
|
|
43
|
+
expiresAt DateTime
|
|
44
|
+
token String
|
|
45
|
+
createdAt DateTime @default(now())
|
|
46
|
+
updatedAt DateTime @updatedAt
|
|
47
|
+
ipAddress String?
|
|
48
|
+
userAgent String?
|
|
49
|
+
userId String
|
|
50
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
51
|
+
impersonatedBy String?
|
|
19
52
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
53
|
+
@@unique([token])
|
|
54
|
+
@@map("session")
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
model Account {
|
|
58
|
+
id String @id
|
|
59
|
+
accountId String
|
|
60
|
+
providerId String
|
|
61
|
+
userId String
|
|
62
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
63
|
+
accessToken String?
|
|
64
|
+
refreshToken String?
|
|
65
|
+
idToken String?
|
|
66
|
+
accessTokenExpiresAt DateTime?
|
|
67
|
+
refreshTokenExpiresAt DateTime?
|
|
68
|
+
scope String?
|
|
69
|
+
password String?
|
|
70
|
+
createdAt DateTime @default(now())
|
|
71
|
+
updatedAt DateTime @updatedAt
|
|
72
|
+
|
|
73
|
+
@@map("account")
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
model Verification {
|
|
77
|
+
id String @id
|
|
78
|
+
identifier String
|
|
79
|
+
value String
|
|
80
|
+
expiresAt DateTime
|
|
81
|
+
createdAt DateTime @default(now())
|
|
82
|
+
updatedAt DateTime @default(now()) @updatedAt
|
|
83
|
+
|
|
84
|
+
@@map("verification")
|
|
85
|
+
}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { Brain, Home, Search, ArrowLeft } from "lucide-react";
|
|
5
|
+
import { motion } from "motion/react";
|
|
6
|
+
|
|
7
|
+
import { Button } from "@/components/ui/button";
|
|
8
|
+
|
|
9
|
+
export default function NotFound() {
|
|
10
|
+
return (
|
|
11
|
+
<div className="bg-background relative flex min-h-screen flex-col items-center justify-center gap-8 overflow-hidden p-6">
|
|
12
|
+
{/* Contenido principal */}
|
|
13
|
+
<div className="relative z-10 flex w-full max-w-2xl flex-col items-center gap-8 text-center">
|
|
14
|
+
{/* Logo y marca */}
|
|
15
|
+
<motion.div
|
|
16
|
+
animate={{ scale: [1, 1.1, 1] }}
|
|
17
|
+
className="flex items-center gap-3 text-2xl font-bold"
|
|
18
|
+
transition={{ duration: 2, repeat: Infinity, ease: "easeInOut" }}
|
|
19
|
+
>
|
|
20
|
+
<div className="from-primary to-accent text-primary-foreground flex size-12 items-center justify-center rounded-xl bg-gradient-to-br shadow-lg">
|
|
21
|
+
<Brain className="size-7" />
|
|
22
|
+
</div>
|
|
23
|
+
<span className="from-foreground to-primary bg-gradient-to-r bg-clip-text text-transparent">
|
|
24
|
+
Nuvace
|
|
25
|
+
</span>
|
|
26
|
+
</motion.div>
|
|
27
|
+
|
|
28
|
+
{/* Número 404 animado */}
|
|
29
|
+
<motion.div
|
|
30
|
+
animate={{
|
|
31
|
+
rotateY: [0, 180, 360],
|
|
32
|
+
scale: [1, 1.05, 1],
|
|
33
|
+
}}
|
|
34
|
+
className="relative"
|
|
35
|
+
transition={{
|
|
36
|
+
duration: 3,
|
|
37
|
+
repeat: Infinity,
|
|
38
|
+
ease: "easeInOut",
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
<h1 className="text-8xl font-black tracking-tighter sm:text-9xl">
|
|
42
|
+
<span className="from-primary to-accent bg-gradient-to-r bg-clip-text text-transparent">
|
|
43
|
+
404
|
|
44
|
+
</span>
|
|
45
|
+
</h1>
|
|
46
|
+
</motion.div>
|
|
47
|
+
|
|
48
|
+
{/* Mensaje principal */}
|
|
49
|
+
<div className="space-y-4">
|
|
50
|
+
<h2 className="text-foreground text-2xl font-bold sm:text-3xl">
|
|
51
|
+
¡Ups! Esta página no existe
|
|
52
|
+
</h2>
|
|
53
|
+
<p className="text-muted-foreground max-w-md text-lg">
|
|
54
|
+
La página que buscas no se encuentra disponible. Es posible que haya sido movida o
|
|
55
|
+
eliminada.
|
|
56
|
+
</p>
|
|
57
|
+
</div>
|
|
58
|
+
|
|
59
|
+
{/* Botones de acción */}
|
|
60
|
+
<div className="flex w-full max-w-sm flex-col gap-4 sm:flex-row">
|
|
61
|
+
<Button asChild className="flex-1 gap-2" size="lg">
|
|
62
|
+
<Link href="/">
|
|
63
|
+
<Home className="size-4" />
|
|
64
|
+
Ir al inicio
|
|
65
|
+
</Link>
|
|
66
|
+
</Button>
|
|
67
|
+
</div>
|
|
68
|
+
|
|
69
|
+
{/* Enlace para volver atrás */}
|
|
70
|
+
<Button
|
|
71
|
+
className="text-muted-foreground hover:text-foreground gap-2"
|
|
72
|
+
variant="ghost"
|
|
73
|
+
onClick={() => window.history.back()}
|
|
74
|
+
>
|
|
75
|
+
<ArrowLeft className="size-4" />
|
|
76
|
+
Volver atrás
|
|
77
|
+
</Button>
|
|
78
|
+
|
|
79
|
+
{/* Información adicional */}
|
|
80
|
+
<div className="border-muted/20 bg-muted/10 mt-8 rounded-lg border p-6 backdrop-blur-sm">
|
|
81
|
+
<p className="text-muted-foreground text-sm">
|
|
82
|
+
Si crees que esto es un error, por favor{" "}
|
|
83
|
+
<Link className="text-primary font-medium hover:underline" href="/panel/resumen">
|
|
84
|
+
contacta con soporte
|
|
85
|
+
</Link>{" "}
|
|
86
|
+
para que podamos ayudarte.
|
|
87
|
+
</p>
|
|
88
|
+
</div>
|
|
89
|
+
</div>
|
|
90
|
+
|
|
91
|
+
{/* Partículas flotantes adicionales para el efecto 404 */}
|
|
92
|
+
<div className="pointer-events-none fixed inset-0">
|
|
93
|
+
{[...Array(5)].map((_, i) => (
|
|
94
|
+
<motion.div
|
|
95
|
+
key={i}
|
|
96
|
+
animate={{
|
|
97
|
+
x: [0, 200, 0],
|
|
98
|
+
y: [0, -200, 0],
|
|
99
|
+
opacity: [0.3, 0.7, 0.3],
|
|
100
|
+
scale: [0.5, 1, 0.5],
|
|
101
|
+
}}
|
|
102
|
+
className="bg-accent absolute h-2 w-2 rounded-full"
|
|
103
|
+
style={{
|
|
104
|
+
left: `${20 + i * 15}%`,
|
|
105
|
+
top: `${30 + i * 10}%`,
|
|
106
|
+
}}
|
|
107
|
+
transition={{
|
|
108
|
+
duration: 5 + i * 0.5,
|
|
109
|
+
ease: "easeInOut",
|
|
110
|
+
repeat: Infinity,
|
|
111
|
+
delay: i * 0.3,
|
|
112
|
+
}}
|
|
113
|
+
/>
|
|
114
|
+
))}
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { createAuthClient } from "better-auth/react";
|
|
2
|
+
import { emailOTPClient, adminClient } from "better-auth/client/plugins";
|
|
3
|
+
|
|
4
|
+
export const authClient = createAuthClient({
|
|
5
|
+
baseURL: process.env.BETTER_AUTH_URL,
|
|
6
|
+
plugins: [emailOTPClient(), adminClient()],
|
|
7
|
+
});
|
|
8
|
+
|
|
9
|
+
export const { signIn, signUp, signOut, useSession } = authClient;
|