create-nextjs-stack 0.1.7 → 0.2.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/README.md +3 -9
- package/bin/cli.js +147 -9
- package/package.json +21 -5
- package/templates/admin/package.json +5 -4
- package/templates/admin/{src/store → store}/index.ts +0 -5
- package/templates/admin/tsconfig.json +1 -1
- package/templates/web/.env.example +16 -17
- package/templates/web/package.json +4 -3
- package/templates/web/src/store/index.ts +0 -5
- package/templates/admin/package-lock.json +0 -6780
- package/templates/web/package-lock.json +0 -6746
- /package/templates/admin/{src/lib → lib}/providers/StoreProvider.tsx +0 -0
- /package/templates/admin/{src/store → store}/actions/index.ts +0 -0
- /package/templates/admin/{src/store → store}/hooks.ts +0 -0
- /package/templates/admin/{src/store → store}/reducers/index.ts +0 -0
- /package/templates/admin/{src/store → store}/types/index.ts +0 -0
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://www.npmjs.com/package/create-nextjs-stack)
|
|
6
6
|
[](https://www.npmjs.com/package/create-nextjs-stack)
|
|
7
7
|
[](https://opensource.org/licenses/MIT)
|
|
8
|
-
[](https://nodejs.org/)
|
|
9
9
|
|
|
10
10
|
**A zero-config CLI to scaffold production-ready Next.js applications.**
|
|
11
11
|
Choose between a marketing landing page, a Supabase admin panel, or both — in one command.
|
|
@@ -336,11 +336,6 @@ NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxx.supabase.co
|
|
|
336
336
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOiJIUzI1NiIsIn...
|
|
337
337
|
SUPABASE_SERVICE_ROLE_KEY=eyJhbGciOiJIUzI1NiIsIn... # Never expose this client-side!
|
|
338
338
|
|
|
339
|
-
# Supabase project meta (used by Supabase CLI / migrations)
|
|
340
|
-
SUPABASE_PROJECT_ID=xxxxxxxxxxxx
|
|
341
|
-
SUPABASE_PROJECT_NAME=my-project
|
|
342
|
-
SUPABASE_DATABASE_PASSWORD=your-db-password
|
|
343
|
-
|
|
344
339
|
# Used to verify on-demand revalidation requests
|
|
345
340
|
REVALIDATION_SECRET=a-random-secret-string
|
|
346
341
|
|
|
@@ -349,7 +344,6 @@ REVALIDATION_SECRET=a-random-secret-string
|
|
|
349
344
|
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your-cloud-name
|
|
350
345
|
CLOUDINARY_API_KEY=000000000000000
|
|
351
346
|
CLOUDINARY_API_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
|
352
|
-
CLOUDINARY_ID=your-cloud-name # Same as CLOUD_NAME, for SDK compat
|
|
353
347
|
CLOUDINARY_URL=cloudinary://API_KEY:API_SECRET@CLOUD_NAME
|
|
354
348
|
|
|
355
349
|
# ─── Site ──────────────────────────────────────────────────────────────────────
|
|
@@ -382,7 +376,7 @@ CLOUDINARY_URL=cloudinary://API_KEY:API_SECRET@CLOUD_NAME
|
|
|
382
376
|
|
|
383
377
|
| Tool | Minimum Version |
|
|
384
378
|
| ------- | --------------- |
|
|
385
|
-
| Node.js |
|
|
379
|
+
| Node.js | 20.x |
|
|
386
380
|
| npm | 9.x |
|
|
387
381
|
|
|
388
382
|
### Available Scripts
|
|
@@ -497,7 +491,7 @@ A: Yes — create two separate Vercel projects pointing to the same repository,
|
|
|
497
491
|
|
|
498
492
|
## 🤝 Contributing
|
|
499
493
|
|
|
500
|
-
Contributions, bug reports, and feature requests are welcome!
|
|
494
|
+
Contributions, bug reports, and feature requests are welcome! Please see [CONTRIBUTING.md](./CONTRIBUTING.md) for detailed guidelines.
|
|
501
495
|
|
|
502
496
|
1. [Open an issue](https://github.com/mburakaltiparmak/create-nextjs-stack/issues) to discuss what you'd like to change.
|
|
503
497
|
2. Fork the repository and create a feature branch:
|
package/bin/cli.js
CHANGED
|
@@ -6,10 +6,39 @@ const { program } = require("commander");
|
|
|
6
6
|
const prompts = require("prompts");
|
|
7
7
|
const chalk = require("chalk");
|
|
8
8
|
const ora = require("ora");
|
|
9
|
+
const { execSync } = require("child_process");
|
|
10
|
+
|
|
11
|
+
function detectPackageManager() {
|
|
12
|
+
const userAgent = process.env.npm_config_user_agent || "";
|
|
13
|
+
if (userAgent.startsWith("yarn")) return "yarn";
|
|
14
|
+
if (userAgent.startsWith("pnpm")) return "pnpm";
|
|
15
|
+
if (userAgent.startsWith("bun")) return "bun";
|
|
16
|
+
return "npm";
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
function isPackageManagerAvailable(pm) {
|
|
20
|
+
try {
|
|
21
|
+
execSync(`${pm} --version`, { stdio: "ignore" });
|
|
22
|
+
return true;
|
|
23
|
+
} catch {
|
|
24
|
+
return false;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
9
27
|
|
|
10
28
|
// Read version from package.json
|
|
11
29
|
const packageJson = require("../package.json");
|
|
12
30
|
|
|
31
|
+
process.on("SIGINT", () => {
|
|
32
|
+
console.log(chalk.red("\n\nOperation cancelled."));
|
|
33
|
+
process.exit(1);
|
|
34
|
+
});
|
|
35
|
+
const updateNotifier = require("update-notifier");
|
|
36
|
+
|
|
37
|
+
const notifier = updateNotifier({ pkg: packageJson, updateCheckInterval: 1000 * 60 * 60 * 24 });
|
|
38
|
+
if (notifier.update) {
|
|
39
|
+
notifier.notify();
|
|
40
|
+
}
|
|
41
|
+
|
|
13
42
|
program
|
|
14
43
|
.name("create-nextjs-stack")
|
|
15
44
|
.version(packageJson.version, "-v, --version", "Output the current version")
|
|
@@ -17,6 +46,17 @@ program
|
|
|
17
46
|
.argument("[project-directory]", "Directory to create the project in")
|
|
18
47
|
.option("-t, --template <type>", "Template type: web, admin, or full-stack")
|
|
19
48
|
.action(async (projectDirectory, options) => {
|
|
49
|
+
const validTemplates = ["web", "admin", "full-stack"];
|
|
50
|
+
if (options.template && !validTemplates.includes(options.template)) {
|
|
51
|
+
console.log(
|
|
52
|
+
chalk.red(
|
|
53
|
+
`\nInvalid template: "${options.template}"\n` +
|
|
54
|
+
`Valid options: ${validTemplates.join(", ")}\n`
|
|
55
|
+
)
|
|
56
|
+
);
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
|
|
20
60
|
let targetDir = projectDirectory;
|
|
21
61
|
|
|
22
62
|
// 1. Get Project Name / Directory
|
|
@@ -162,24 +202,122 @@ program
|
|
|
162
202
|
|
|
163
203
|
spinner.succeed("Scaffolding complete!");
|
|
164
204
|
|
|
165
|
-
|
|
205
|
+
// Skip install prompts if testing
|
|
206
|
+
if (process.env.NODE_ENV !== "test" && process.env.VITEST !== "true") {
|
|
207
|
+
const detectedPm = detectPackageManager();
|
|
166
208
|
|
|
167
|
-
|
|
209
|
+
const { packageManager } = await prompts({
|
|
210
|
+
type: "select",
|
|
211
|
+
name: "packageManager",
|
|
212
|
+
message: "Which package manager would you like to use?",
|
|
213
|
+
choices: [
|
|
214
|
+
{ title: "npm", value: "npm" },
|
|
215
|
+
{ title: "yarn", value: "yarn" },
|
|
216
|
+
{ title: "pnpm", value: "pnpm" },
|
|
217
|
+
{ title: "bun", value: "bun" },
|
|
218
|
+
].filter((choice) => isPackageManagerAvailable(choice.value)),
|
|
219
|
+
initial: ["npm", "yarn", "pnpm", "bun"].indexOf(detectedPm) >= 0 ? ["npm", "yarn", "pnpm", "bun"].indexOf(detectedPm) : 0,
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
if (!packageManager) {
|
|
223
|
+
console.log(chalk.red("\nOperation cancelled."));
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
const { shouldInstall } = await prompts({
|
|
228
|
+
type: "confirm",
|
|
229
|
+
name: "shouldInstall",
|
|
230
|
+
message: `Install dependencies with ${packageManager}?`,
|
|
231
|
+
initial: true,
|
|
232
|
+
});
|
|
233
|
+
|
|
234
|
+
if (shouldInstall === undefined) {
|
|
235
|
+
console.log(chalk.red("\nOperation cancelled."));
|
|
236
|
+
process.exit(1);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (shouldInstall) {
|
|
240
|
+
const installTargets =
|
|
241
|
+
templateType === "full-stack"
|
|
242
|
+
? [path.join(root, "web"), path.join(root, "admin")]
|
|
243
|
+
: [root];
|
|
244
|
+
|
|
245
|
+
for (const target of installTargets) {
|
|
246
|
+
const dirName = path.basename(target);
|
|
247
|
+
const installSpinner = ora(
|
|
248
|
+
`Installing dependencies in ${dirName}...`,
|
|
249
|
+
).start();
|
|
250
|
+
|
|
251
|
+
try {
|
|
252
|
+
const installCmd =
|
|
253
|
+
packageManager === "yarn" ? "yarn" : `${packageManager} install`;
|
|
254
|
+
|
|
255
|
+
execSync(installCmd, {
|
|
256
|
+
cwd: target,
|
|
257
|
+
stdio: "pipe",
|
|
258
|
+
});
|
|
259
|
+
|
|
260
|
+
installSpinner.succeed(`Dependencies installed in ${dirName}`);
|
|
261
|
+
} catch (error) {
|
|
262
|
+
installSpinner.fail(`Failed to install dependencies in ${dirName}`);
|
|
263
|
+
console.log(
|
|
264
|
+
chalk.yellow(
|
|
265
|
+
` You can install manually: cd ${dirName} && ${packageManager} install`,
|
|
266
|
+
),
|
|
267
|
+
);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
console.log(`\n${chalk.green("Success!")} Created project at ${root}\n`);
|
|
168
273
|
console.log("Next steps:");
|
|
169
274
|
console.log(chalk.cyan(` cd ${appName}`));
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
275
|
+
|
|
276
|
+
if (templateType === "full-stack") {
|
|
277
|
+
console.log(" Then go to either web or admin folder:");
|
|
278
|
+
console.log(chalk.cyan(` cd web`));
|
|
279
|
+
if (!shouldInstall) {
|
|
280
|
+
console.log(chalk.cyan(` ${packageManager || "npm"} install`));
|
|
281
|
+
}
|
|
282
|
+
console.log(chalk.cyan(` ${packageManager || "npm"} run dev`));
|
|
283
|
+
} else {
|
|
284
|
+
if (!shouldInstall) {
|
|
285
|
+
console.log(chalk.cyan(` ${packageManager || "npm"} install`));
|
|
286
|
+
}
|
|
287
|
+
console.log(chalk.cyan(` ${packageManager || "npm"} run dev`));
|
|
288
|
+
}
|
|
174
289
|
} else {
|
|
290
|
+
// Fallback for tests
|
|
291
|
+
console.log(`\nSuccess! Created project at ${root}\n`);
|
|
175
292
|
console.log("Next steps:");
|
|
176
293
|
console.log(chalk.cyan(` cd ${appName}`));
|
|
177
|
-
|
|
178
|
-
|
|
294
|
+
if (templateType === "full-stack") {
|
|
295
|
+
console.log(" Then go to either web or admin folder:");
|
|
296
|
+
console.log(chalk.cyan(` cd web`));
|
|
297
|
+
console.log(chalk.cyan(` npm install`));
|
|
298
|
+
console.log(chalk.cyan(` npm run dev`));
|
|
299
|
+
} else {
|
|
300
|
+
console.log(chalk.cyan(` npm install`));
|
|
301
|
+
console.log(chalk.cyan(` npm run dev`));
|
|
302
|
+
}
|
|
179
303
|
}
|
|
180
304
|
} catch (error) {
|
|
181
305
|
spinner.fail("Error scaffolding project.");
|
|
182
|
-
|
|
306
|
+
|
|
307
|
+
if (error.code === "EACCES") {
|
|
308
|
+
console.error(
|
|
309
|
+
chalk.red("\nPermission denied. Try running with elevated privileges.")
|
|
310
|
+
);
|
|
311
|
+
} else if (error.code === "ENOSPC") {
|
|
312
|
+
console.error(chalk.red("\nNo disk space available."));
|
|
313
|
+
} else {
|
|
314
|
+
console.error(chalk.red(`\n${error.message || error}`));
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
if (process.env.DEBUG) {
|
|
318
|
+
console.error("\nFull error:", error);
|
|
319
|
+
}
|
|
320
|
+
|
|
183
321
|
process.exit(1);
|
|
184
322
|
}
|
|
185
323
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-nextjs-stack",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "CLI to scaffold Next.js Landing Page and Supabase Admin Panel",
|
|
5
|
+
"type": "commonjs",
|
|
5
6
|
"private": false,
|
|
6
7
|
"bin": {
|
|
7
8
|
"create-nextjs-stack": "./bin/cli.js"
|
|
@@ -10,26 +11,40 @@
|
|
|
10
11
|
"bin",
|
|
11
12
|
"templates"
|
|
12
13
|
],
|
|
14
|
+
"exports": {
|
|
15
|
+
".": "./bin/cli.js"
|
|
16
|
+
},
|
|
13
17
|
"scripts": {
|
|
14
|
-
"test": "vitest run"
|
|
18
|
+
"test": "vitest run",
|
|
19
|
+
"test:watch": "vitest",
|
|
20
|
+
"test:coverage": "vitest run --coverage",
|
|
21
|
+
"test:verbose": "vitest run --reporter=verbose"
|
|
15
22
|
},
|
|
16
23
|
"dependencies": {
|
|
17
24
|
"chalk": "^4.1.2",
|
|
18
25
|
"commander": "^14.0.3",
|
|
19
26
|
"fs-extra": "^11.3.3",
|
|
20
27
|
"ora": "^5.4.1",
|
|
21
|
-
"prompts": "^2.4.2"
|
|
28
|
+
"prompts": "^2.4.2",
|
|
29
|
+
"update-notifier": "^5.1.0"
|
|
22
30
|
},
|
|
23
31
|
"engines": {
|
|
24
|
-
"node": ">=
|
|
32
|
+
"node": ">=20.0.0"
|
|
25
33
|
},
|
|
26
34
|
"keywords": [
|
|
27
35
|
"nextjs",
|
|
36
|
+
"next",
|
|
28
37
|
"starter",
|
|
29
38
|
"template",
|
|
39
|
+
"scaffold",
|
|
40
|
+
"cli",
|
|
41
|
+
"create",
|
|
30
42
|
"supabase",
|
|
31
43
|
"admin",
|
|
32
|
-
"
|
|
44
|
+
"tailwind",
|
|
45
|
+
"typescript",
|
|
46
|
+
"react",
|
|
47
|
+
"boilerplate"
|
|
33
48
|
],
|
|
34
49
|
"author": "Mehmet Burak Altıparmak <mburakaltiparmak@gmail.com>",
|
|
35
50
|
"license": "MIT",
|
|
@@ -44,6 +59,7 @@
|
|
|
44
59
|
"devDependencies": {
|
|
45
60
|
"@types/fs-extra": "^11.0.4",
|
|
46
61
|
"@types/node": "^25.2.3",
|
|
62
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
47
63
|
"execa": "^9.6.1",
|
|
48
64
|
"vitest": "^4.0.18"
|
|
49
65
|
}
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
"name": "supabase-admin-template",
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"private": true,
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=20.0.0"
|
|
7
|
+
},
|
|
5
8
|
"scripts": {
|
|
6
9
|
"dev": "next dev",
|
|
7
10
|
"build": "next build",
|
|
@@ -16,12 +19,11 @@
|
|
|
16
19
|
"clsx": "^2.1.1",
|
|
17
20
|
"lucide-react": "^0.563.0",
|
|
18
21
|
"next": "^16.1.6",
|
|
19
|
-
"react": "^19.2.
|
|
20
|
-
"react-dom": "^19.2.
|
|
22
|
+
"react": "^19.2.4",
|
|
23
|
+
"react-dom": "^19.2.4",
|
|
21
24
|
"react-hook-form": "^7.71.1",
|
|
22
25
|
"react-redux": "^9.2.0",
|
|
23
26
|
"react-toastify": "^11.0.3",
|
|
24
|
-
"redux-logger": "^3.0.6",
|
|
25
27
|
"tailwind-merge": "^3.5.0"
|
|
26
28
|
},
|
|
27
29
|
"devDependencies": {
|
|
@@ -29,7 +31,6 @@
|
|
|
29
31
|
"@types/node": "^20",
|
|
30
32
|
"@types/react": "^19",
|
|
31
33
|
"@types/react-dom": "^19",
|
|
32
|
-
"@types/redux-logger": "^3.0.13",
|
|
33
34
|
"babel-plugin-react-compiler": "1.0.0",
|
|
34
35
|
"eslint": "^9",
|
|
35
36
|
"eslint-config-next": "^16.1.6",
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { configureStore } from '@reduxjs/toolkit';
|
|
2
|
-
import logger from 'redux-logger';
|
|
3
2
|
import rootReducer from './reducers';
|
|
4
3
|
|
|
5
4
|
const store = configureStore({
|
|
6
5
|
reducer: rootReducer,
|
|
7
|
-
middleware: (getDefaultMiddleware) =>
|
|
8
|
-
process.env.NODE_ENV !== 'production'
|
|
9
|
-
? getDefaultMiddleware().concat(logger)
|
|
10
|
-
: getDefaultMiddleware(),
|
|
11
6
|
});
|
|
12
7
|
|
|
13
8
|
// Inferred types — export and use via store/hooks.ts
|
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
# Supabase Configuration
|
|
6
|
-
SUPABASE_DATABASE_PASSWORD=your_supabase_database_password_here
|
|
7
|
-
SUPABASE_PROJECT_NAME=your_supabase_project_name_here
|
|
8
|
-
SUPABASE_PROJECT_ID=your_supabase_project_id_here
|
|
9
|
-
NEXT_PUBLIC_SUPABASE_URL=your_supabase_url_here
|
|
10
|
-
SUPABASE_PUBLISHABLE_KEY=your_supabase_publishable_key_here
|
|
11
|
-
SUPABASE_SECRET_KEY=your_supabase_secret_key_here
|
|
1
|
+
# ─── Supabase ──────────────────────────────────────────────────────────────────
|
|
2
|
+
# https://supabase.com → Project Settings → API
|
|
3
|
+
NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxx.supabase.co
|
|
12
4
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_supabase_anon_key_here
|
|
13
5
|
SUPABASE_SERVICE_ROLE_KEY=your_supabase_service_role_key_here
|
|
14
|
-
REVALIDATION_SECRET=your_revalidation_secret_here
|
|
15
6
|
|
|
16
|
-
#
|
|
7
|
+
# ─── Email (Resend) ───────────────────────────────────────────────────────────
|
|
8
|
+
# https://resend.com → API Keys
|
|
9
|
+
RESEND_API_KEY=your_resend_api_key_here
|
|
10
|
+
RESEND_FROM_EMAIL=hello@yourdomain.com
|
|
11
|
+
|
|
12
|
+
# ─── Cloudinary ────────────────────────────────────────────────────────────────
|
|
13
|
+
# https://cloudinary.com → Dashboard
|
|
14
|
+
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloud_name_here
|
|
17
15
|
CLOUDINARY_API_KEY=your_cloudinary_api_key_here
|
|
18
16
|
CLOUDINARY_API_SECRET=your_cloudinary_api_secret_here
|
|
19
|
-
CLOUDINARY_ID=your_cloud_name_here
|
|
20
|
-
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=your_cloud_name_here
|
|
21
17
|
CLOUDINARY_URL=cloudinary://your_api_key:your_api_secret@your_cloud_name
|
|
22
18
|
|
|
23
|
-
# Site
|
|
19
|
+
# ─── Site ──────────────────────────────────────────────────────────────────────
|
|
24
20
|
NEXT_PUBLIC_SITE_URL=http://localhost:3000
|
|
25
|
-
NEXT_PUBLIC_GA_ID=your_google_analytics_id_here
|
|
21
|
+
NEXT_PUBLIC_GA_ID=your_google_analytics_id_here
|
|
22
|
+
|
|
23
|
+
# ─── Revalidation ─────────────────────────────────────────────────────────────
|
|
24
|
+
REVALIDATION_SECRET=your_random_secret_string_here
|
|
@@ -3,6 +3,9 @@
|
|
|
3
3
|
"version": "0.1.0",
|
|
4
4
|
"description": "Next.js Landing Page Starter",
|
|
5
5
|
"private": true,
|
|
6
|
+
"engines": {
|
|
7
|
+
"node": ">=20.0.0"
|
|
8
|
+
},
|
|
6
9
|
"scripts": {
|
|
7
10
|
"dev": "next dev --turbopack",
|
|
8
11
|
"build": "next build --turbopack",
|
|
@@ -26,10 +29,9 @@
|
|
|
26
29
|
"react-hook-form": "^7.70.0",
|
|
27
30
|
"react-icons": "^5.5.0",
|
|
28
31
|
"react-redux": "^9.2.0",
|
|
29
|
-
"redux-logger": "^3.0.6",
|
|
30
32
|
"react-toastify": "^11.0.5",
|
|
31
33
|
"resend": "^6.6.0",
|
|
32
|
-
"zod": "^
|
|
34
|
+
"zod": "^3.25.0"
|
|
33
35
|
},
|
|
34
36
|
"devDependencies": {
|
|
35
37
|
"@eslint/eslintrc": "^3",
|
|
@@ -37,7 +39,6 @@
|
|
|
37
39
|
"@types/node": "^20",
|
|
38
40
|
"@types/react": "^19",
|
|
39
41
|
"@types/react-dom": "^19",
|
|
40
|
-
"@types/redux-logger": "^3.0.13",
|
|
41
42
|
"eslint": "^9",
|
|
42
43
|
"eslint-config-next": "^16.1.6",
|
|
43
44
|
"tailwindcss": "^4",
|
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import { configureStore } from '@reduxjs/toolkit';
|
|
2
|
-
import logger from 'redux-logger';
|
|
3
2
|
import rootReducer from './reducers';
|
|
4
3
|
|
|
5
4
|
const store = configureStore({
|
|
6
5
|
reducer: rootReducer,
|
|
7
|
-
middleware: (getDefaultMiddleware) =>
|
|
8
|
-
process.env.NODE_ENV !== 'production'
|
|
9
|
-
? getDefaultMiddleware().concat(logger)
|
|
10
|
-
: getDefaultMiddleware(),
|
|
11
6
|
});
|
|
12
7
|
|
|
13
8
|
// Inferred types — export and use via store/hooks.ts
|