create-pnpm-custom-app 1.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/README.md +217 -0
- package/bin/cli.js +185 -0
- package/package.json +39 -0
- package/templates/.github/copilot-instructions.md +184 -0
- package/templates/.nvmrc +1 -0
- package/templates/.vscode/settings.json +51 -0
- package/templates/CONTRIBUTING.md +184 -0
- package/templates/LICENSE +21 -0
- package/templates/README.md +324 -0
- package/templates/apps/api/.env.example +36 -0
- package/templates/apps/api/.prettierrc.json +7 -0
- package/templates/apps/api/eslint.config.js +17 -0
- package/templates/apps/api/gitignore +45 -0
- package/templates/apps/api/jest.config.ts +22 -0
- package/templates/apps/api/package.json +49 -0
- package/templates/apps/api/src/app.ts +121 -0
- package/templates/apps/api/src/config/config.ts +38 -0
- package/templates/apps/api/src/config/logger.ts +57 -0
- package/templates/apps/api/src/db/mongo.ts +30 -0
- package/templates/apps/api/src/index.ts +40 -0
- package/templates/apps/api/src/middlewares/middleware.ts +75 -0
- package/templates/apps/api/src/models/example.model.ts +89 -0
- package/templates/apps/api/src/routes/routes.ts +54 -0
- package/templates/apps/api/src/schemas/swagger.schema.ts +58 -0
- package/templates/apps/api/src/services/example.service.ts +63 -0
- package/templates/apps/api/src/tests/health.test.ts +90 -0
- package/templates/apps/api/src/tests/helpers/test-helpers.ts +40 -0
- package/templates/apps/api/src/tests/mocks/mocks.ts +29 -0
- package/templates/apps/api/src/tests/setup.ts +11 -0
- package/templates/apps/api/src/types/fastify.d.ts +44 -0
- package/templates/apps/api/tsconfig.json +24 -0
- package/templates/apps/web/.env.example +25 -0
- package/templates/apps/web/.prettierignore +7 -0
- package/templates/apps/web/.prettierrc +9 -0
- package/templates/apps/web/app/ICONS.md +42 -0
- package/templates/apps/web/app/[locale]/(routes)/layout.tsx +13 -0
- package/templates/apps/web/app/[locale]/(routes)/page.tsx +49 -0
- package/templates/apps/web/app/[locale]/[...not-found]/page.tsx +8 -0
- package/templates/apps/web/app/[locale]/layout.tsx +35 -0
- package/templates/apps/web/app/[locale]/not-found.tsx +12 -0
- package/templates/apps/web/app/components/layout/Footer.component.tsx +30 -0
- package/templates/apps/web/app/components/layout/Nav.component.tsx +34 -0
- package/templates/apps/web/app/components/ui/README.md +39 -0
- package/templates/apps/web/app/components/ui/atoms/README.md +55 -0
- package/templates/apps/web/app/components/ui/molecules/README.md +51 -0
- package/templates/apps/web/app/globals.css +104 -0
- package/templates/apps/web/app/icon.svg +5 -0
- package/templates/apps/web/app/layout.tsx +37 -0
- package/templates/apps/web/app/manifest.json +22 -0
- package/templates/apps/web/app/providers.tsx +25 -0
- package/templates/apps/web/app/robots.ts +12 -0
- package/templates/apps/web/app/sitemap.ts +18 -0
- package/templates/apps/web/eslint.config.mjs +16 -0
- package/templates/apps/web/gitignore +56 -0
- package/templates/apps/web/hooks/README.md +25 -0
- package/templates/apps/web/i18n/config.ts +9 -0
- package/templates/apps/web/i18n/request.ts +15 -0
- package/templates/apps/web/interfaces/README.md +5 -0
- package/templates/apps/web/lib/README.md +45 -0
- package/templates/apps/web/lib/utils.ts +18 -0
- package/templates/apps/web/messages/en.json +34 -0
- package/templates/apps/web/messages/es.json +34 -0
- package/templates/apps/web/next.config.ts +50 -0
- package/templates/apps/web/package.json +34 -0
- package/templates/apps/web/postcss.config.mjs +7 -0
- package/templates/apps/web/proxy.ts +17 -0
- package/templates/apps/web/public/README.md +7 -0
- package/templates/apps/web/tsconfig.json +27 -0
- package/templates/apps/web/types/README.md +3 -0
- package/templates/docs/README.md +13 -0
- package/templates/gitignore-root +51 -0
- package/templates/package.json +30 -0
- package/templates/packages/shared/eslint.config.js +26 -0
- package/templates/packages/shared/package.json +22 -0
- package/templates/packages/shared/src/index.ts +39 -0
- package/templates/packages/shared/tsconfig.json +19 -0
- package/templates/pnpm-workspace.yaml +3 -0
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
@import 'tailwindcss';
|
|
2
|
+
|
|
3
|
+
/* ==================================================
|
|
4
|
+
TAILWIND THEME CONFIGURATION
|
|
5
|
+
================================================== */
|
|
6
|
+
|
|
7
|
+
@theme {
|
|
8
|
+
/* ==================================================
|
|
9
|
+
CUSTOM COLORS
|
|
10
|
+
================================================== */
|
|
11
|
+
--color-primary: #3b82f6;
|
|
12
|
+
--color-primary-foreground: #ffffff;
|
|
13
|
+
--color-secondary: #10b981;
|
|
14
|
+
--color-secondary-foreground: #ffffff;
|
|
15
|
+
|
|
16
|
+
/* ==================================================
|
|
17
|
+
LIGHT MODE COLORS
|
|
18
|
+
================================================== */
|
|
19
|
+
--color-background: #ffffff;
|
|
20
|
+
--color-foreground: #0a0a0a;
|
|
21
|
+
--color-card: #ffffff;
|
|
22
|
+
--color-card-foreground: #0a0a0a;
|
|
23
|
+
--color-popover: #ffffff;
|
|
24
|
+
--color-popover-foreground: #0a0a0a;
|
|
25
|
+
--color-muted: #f1f5f9;
|
|
26
|
+
--color-muted-foreground: #64748b;
|
|
27
|
+
--color-accent: #f1f5f9;
|
|
28
|
+
--color-accent-foreground: #0f172a;
|
|
29
|
+
--color-destructive: #ef4444;
|
|
30
|
+
--color-destructive-foreground: #fafafa;
|
|
31
|
+
--color-border: #e2e8f0;
|
|
32
|
+
--color-input: #e2e8f0;
|
|
33
|
+
--color-ring: #3b82f6;
|
|
34
|
+
|
|
35
|
+
/* ==================================================
|
|
36
|
+
BORDER RADIUS
|
|
37
|
+
================================================== */
|
|
38
|
+
--radius: 0.5rem;
|
|
39
|
+
|
|
40
|
+
/* ==================================================
|
|
41
|
+
CUSTOM SPACING (if needed)
|
|
42
|
+
================================================== */
|
|
43
|
+
/* --spacing-section: 4rem; */
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/* ==================================================
|
|
47
|
+
DARK MODE CONFIGURATION
|
|
48
|
+
================================================== */
|
|
49
|
+
|
|
50
|
+
:root {
|
|
51
|
+
color-scheme: light dark;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.dark {
|
|
55
|
+
color-scheme: dark;
|
|
56
|
+
|
|
57
|
+
--color-primary: #60a5fa;
|
|
58
|
+
--color-secondary: #34d399;
|
|
59
|
+
|
|
60
|
+
--color-background: #0a0a0a;
|
|
61
|
+
--color-foreground: #fafafa;
|
|
62
|
+
--color-card: #0a0a0a;
|
|
63
|
+
--color-card-foreground: #fafafa;
|
|
64
|
+
--color-popover: #0a0a0a;
|
|
65
|
+
--color-popover-foreground: #fafafa;
|
|
66
|
+
--color-muted: #1e293b;
|
|
67
|
+
--color-muted-foreground: #94a3b8;
|
|
68
|
+
--color-accent: #1e293b;
|
|
69
|
+
--color-accent-foreground: #fafafa;
|
|
70
|
+
--color-destructive: #7f1d1d;
|
|
71
|
+
--color-border: #1e293b;
|
|
72
|
+
--color-input: #1e293b;
|
|
73
|
+
--color-ring: #60a5fa;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/* ==================================================
|
|
77
|
+
BASE STYLES
|
|
78
|
+
================================================== */
|
|
79
|
+
|
|
80
|
+
* {
|
|
81
|
+
border-color: var(--color-border);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
body {
|
|
85
|
+
background-color: var(--color-background);
|
|
86
|
+
color: var(--color-foreground);
|
|
87
|
+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
|
|
88
|
+
Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/* ==================================================
|
|
92
|
+
UTILITY CLASSES (optional custom utilities)
|
|
93
|
+
================================================== */
|
|
94
|
+
|
|
95
|
+
/* Example: Smooth scrolling */
|
|
96
|
+
html {
|
|
97
|
+
scroll-behavior: smooth;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Example: Focus visible styling */
|
|
101
|
+
:focus-visible {
|
|
102
|
+
outline: 2px solid var(--color-ring);
|
|
103
|
+
outline-offset: 2px;
|
|
104
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
<svg width="512" height="512" viewBox="0 0 512 512" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<rect width="512" height="512" rx="128" fill="#3b82f6"/>
|
|
3
|
+
<path d="M256 128C238.3 128 224 142.3 224 160V256C224 273.7 238.3 288 256 288C273.7 288 288 273.7 288 256V160C288 142.3 273.7 128 256 128Z" fill="white"/>
|
|
4
|
+
<circle cx="256" cy="352" r="32" fill="white"/>
|
|
5
|
+
</svg>
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { Metadata } from 'next';
|
|
2
|
+
import { Providers } from './providers';
|
|
3
|
+
import './globals.css';
|
|
4
|
+
|
|
5
|
+
export const metadata: Metadata = {
|
|
6
|
+
title: '{{PROJECT_NAME}}',
|
|
7
|
+
description: 'A professional full-stack monorepo with Next.js, Fastify, and pnpm workspaces',
|
|
8
|
+
metadataBase: new URL('https://your-domain.com'),
|
|
9
|
+
keywords: ['nextjs', 'fastify', 'monorepo', 'pnpm', 'typescript'],
|
|
10
|
+
authors: [{ name: 'Your Name' }],
|
|
11
|
+
openGraph: {
|
|
12
|
+
title: '{{PROJECT_NAME}}',
|
|
13
|
+
description: 'A professional full-stack monorepo',
|
|
14
|
+
type: 'website',
|
|
15
|
+
locale: 'es_ES',
|
|
16
|
+
alternateLocale: 'en_US',
|
|
17
|
+
},
|
|
18
|
+
twitter: {
|
|
19
|
+
card: 'summary_large_image',
|
|
20
|
+
title: '{{PROJECT_NAME}}',
|
|
21
|
+
description: 'A professional full-stack monorepo',
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export default function RootLayout({
|
|
26
|
+
children,
|
|
27
|
+
}: Readonly<{
|
|
28
|
+
children: React.ReactNode;
|
|
29
|
+
}>) {
|
|
30
|
+
return (
|
|
31
|
+
<html suppressHydrationWarning>
|
|
32
|
+
<body>
|
|
33
|
+
<Providers>{children}</Providers>
|
|
34
|
+
</body>
|
|
35
|
+
</html>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{PROJECT_NAME}}",
|
|
3
|
+
"short_name": "{{PROJECT_NAME}}",
|
|
4
|
+
"description": "A professional full-stack monorepo",
|
|
5
|
+
"start_url": "/",
|
|
6
|
+
"display": "standalone",
|
|
7
|
+
"background_color": "#ffffff",
|
|
8
|
+
"theme_color": "#3b82f6",
|
|
9
|
+
"icons": [
|
|
10
|
+
{
|
|
11
|
+
"src": "/icon.png",
|
|
12
|
+
"sizes": "512x512",
|
|
13
|
+
"type": "image/png",
|
|
14
|
+
"purpose": "any maskable"
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"src": "/apple-icon.png",
|
|
18
|
+
"sizes": "180x180",
|
|
19
|
+
"type": "image/png"
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Providers component
|
|
7
|
+
*
|
|
8
|
+
* This component wraps the application with context providers.
|
|
9
|
+
* Add your theme providers, state management providers, etc. here.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // Add a theme provider:
|
|
13
|
+
* import { ThemeProvider } from 'next-themes';
|
|
14
|
+
*
|
|
15
|
+
* export function Providers({ children }: { children: ReactNode }) {
|
|
16
|
+
* return (
|
|
17
|
+
* <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
|
|
18
|
+
* {children}
|
|
19
|
+
* </ThemeProvider>
|
|
20
|
+
* );
|
|
21
|
+
* }
|
|
22
|
+
*/
|
|
23
|
+
export function Providers({ children }: { children: ReactNode }) {
|
|
24
|
+
return <>{children}</>;
|
|
25
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { MetadataRoute } from 'next';
|
|
2
|
+
|
|
3
|
+
export default function sitemap(): MetadataRoute.Sitemap {
|
|
4
|
+
return [
|
|
5
|
+
{
|
|
6
|
+
url: 'https://your-domain.com',
|
|
7
|
+
lastModified: new Date(),
|
|
8
|
+
changeFrequency: 'yearly',
|
|
9
|
+
priority: 1,
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
url: 'https://your-domain.com/about',
|
|
13
|
+
lastModified: new Date(),
|
|
14
|
+
changeFrequency: 'monthly',
|
|
15
|
+
priority: 0.8,
|
|
16
|
+
},
|
|
17
|
+
];
|
|
18
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# Dependencies
|
|
2
|
+
node_modules/
|
|
3
|
+
.pnp
|
|
4
|
+
.pnp.js
|
|
5
|
+
|
|
6
|
+
# Next.js
|
|
7
|
+
.next/
|
|
8
|
+
out/
|
|
9
|
+
*.tsbuildinfo
|
|
10
|
+
next-env.d.ts
|
|
11
|
+
|
|
12
|
+
# Production
|
|
13
|
+
build/
|
|
14
|
+
dist/
|
|
15
|
+
|
|
16
|
+
# Environment variables
|
|
17
|
+
.env
|
|
18
|
+
.env*.local
|
|
19
|
+
!.env.example
|
|
20
|
+
!.env.local.example
|
|
21
|
+
|
|
22
|
+
# Logs
|
|
23
|
+
*.log
|
|
24
|
+
npm-debug.log*
|
|
25
|
+
yarn-debug.log*
|
|
26
|
+
yarn-error.log*
|
|
27
|
+
pnpm-debug.log*
|
|
28
|
+
lerna-debug.log*
|
|
29
|
+
|
|
30
|
+
# OS
|
|
31
|
+
.DS_Store
|
|
32
|
+
*.pem
|
|
33
|
+
Thumbs.db
|
|
34
|
+
|
|
35
|
+
# IDE
|
|
36
|
+
.vscode/*
|
|
37
|
+
!.vscode/settings.json
|
|
38
|
+
!.vscode/extensions.json
|
|
39
|
+
.idea/
|
|
40
|
+
*.swp
|
|
41
|
+
*.swo
|
|
42
|
+
*~
|
|
43
|
+
|
|
44
|
+
# Testing
|
|
45
|
+
coverage/
|
|
46
|
+
.nyc_output
|
|
47
|
+
|
|
48
|
+
# Turbopack
|
|
49
|
+
.turbopack/
|
|
50
|
+
|
|
51
|
+
# Vercel
|
|
52
|
+
.vercel
|
|
53
|
+
|
|
54
|
+
# Temporary files
|
|
55
|
+
*.tmp
|
|
56
|
+
.cache
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Hooks
|
|
2
|
+
|
|
3
|
+
Custom React hooks for reusable logic across components.
|
|
4
|
+
|
|
5
|
+
## Examples
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
// useMediaQuery.ts
|
|
9
|
+
import { useState, useEffect } from 'react';
|
|
10
|
+
|
|
11
|
+
export function useMediaQuery(query: string): boolean {
|
|
12
|
+
const [matches, setMatches] = useState(false);
|
|
13
|
+
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
const media = window.matchMedia(query);
|
|
16
|
+
setMatches(media.matches);
|
|
17
|
+
|
|
18
|
+
const listener = () => setMatches(media.matches);
|
|
19
|
+
media.addEventListener('change', listener);
|
|
20
|
+
return () => media.removeEventListener('change', listener);
|
|
21
|
+
}, [query]);
|
|
22
|
+
|
|
23
|
+
return matches;
|
|
24
|
+
}
|
|
25
|
+
```
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { getRequestConfig } from 'next-intl/server';
|
|
2
|
+
import { locales, Locale } from './config';
|
|
3
|
+
|
|
4
|
+
export default getRequestConfig(async ({ requestLocale }) => {
|
|
5
|
+
let locale = await requestLocale;
|
|
6
|
+
|
|
7
|
+
if (!locale || !locales.includes(locale as Locale)) {
|
|
8
|
+
locale = 'es';
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
locale,
|
|
13
|
+
messages: (await import(`../messages/${locale}.json`)).default,
|
|
14
|
+
};
|
|
15
|
+
});
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Lib Folder
|
|
2
|
+
|
|
3
|
+
This folder contains utility functions, API clients, and helper modules.
|
|
4
|
+
|
|
5
|
+
## Purpose
|
|
6
|
+
|
|
7
|
+
- **API Clients**: Functions to interact with the backend API
|
|
8
|
+
- **Utilities**: Helper functions used across the application
|
|
9
|
+
- **Constants**: Shared constants and configuration
|
|
10
|
+
- **Helpers**: Common helper functions
|
|
11
|
+
|
|
12
|
+
## Example Structure
|
|
13
|
+
|
|
14
|
+
```txt
|
|
15
|
+
lib/
|
|
16
|
+
├── api.ts # Generic API client
|
|
17
|
+
├── utils.ts # Utility functions
|
|
18
|
+
├── constants.ts # App constants
|
|
19
|
+
└── services/
|
|
20
|
+
├── auth.ts # Authentication service
|
|
21
|
+
└── users.ts # Users service
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Example API Client
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
// api.ts
|
|
28
|
+
const API_URL = process.env.NEXT_PUBLIC_API_URL || 'http://localhost:3002';
|
|
29
|
+
|
|
30
|
+
export async function fetcher<T>(endpoint: string, options?: RequestInit): Promise<T> {
|
|
31
|
+
const response = await fetch(`${API_URL}${endpoint}`, {
|
|
32
|
+
...options,
|
|
33
|
+
headers: {
|
|
34
|
+
'Content-Type': 'application/json',
|
|
35
|
+
...options?.headers,
|
|
36
|
+
},
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (!response.ok) {
|
|
40
|
+
throw new Error(`API Error: ${response.statusText}`);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return response.json();
|
|
44
|
+
}
|
|
45
|
+
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type ClassValue, clsx } from 'clsx';
|
|
2
|
+
import { twMerge } from 'tailwind-merge';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Utility function to merge Tailwind CSS classes
|
|
6
|
+
*
|
|
7
|
+
* @param inputs - Class values to merge
|
|
8
|
+
* @returns Merged class string
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* cn('px-2 py-1', 'bg-primary') // 'px-2 py-1 bg-primary'
|
|
13
|
+
* cn('px-2', someCondition && 'bg-primary') // 'px-2 bg-primary' if someCondition is true
|
|
14
|
+
* ```
|
|
15
|
+
*/
|
|
16
|
+
export function cn(...inputs: ClassValue[]) {
|
|
17
|
+
return twMerge(clsx(inputs));
|
|
18
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"loading": "Loading...",
|
|
4
|
+
"error": "An error occurred",
|
|
5
|
+
"success": "Success!",
|
|
6
|
+
"cancel": "Cancel",
|
|
7
|
+
"save": "Save",
|
|
8
|
+
"delete": "Delete",
|
|
9
|
+
"edit": "Edit",
|
|
10
|
+
"create": "Create",
|
|
11
|
+
"update": "Update",
|
|
12
|
+
"search": "Search",
|
|
13
|
+
"filter": "Filter",
|
|
14
|
+
"clear": "Clear",
|
|
15
|
+
"close": "Close",
|
|
16
|
+
"back": "Back",
|
|
17
|
+
"next": "Next",
|
|
18
|
+
"previous": "Previous",
|
|
19
|
+
"submit": "Submit",
|
|
20
|
+
"confirm": "Confirm"
|
|
21
|
+
},
|
|
22
|
+
"nav": {
|
|
23
|
+
"home": "Home",
|
|
24
|
+
"about": "About",
|
|
25
|
+
"contact": "Contact"
|
|
26
|
+
},
|
|
27
|
+
"home": {
|
|
28
|
+
"title": "Welcome to {{PROJECT_NAME}}",
|
|
29
|
+
"description": "A professional full-stack monorepo with Next.js, Fastify, and pnpm workspaces"
|
|
30
|
+
},
|
|
31
|
+
"footer": {
|
|
32
|
+
"copyright": "© {year} {{PROJECT_NAME}}. All rights reserved."
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"common": {
|
|
3
|
+
"loading": "Cargando...",
|
|
4
|
+
"error": "Ocurrió un error",
|
|
5
|
+
"success": "¡Éxito!",
|
|
6
|
+
"cancel": "Cancelar",
|
|
7
|
+
"save": "Guardar",
|
|
8
|
+
"delete": "Eliminar",
|
|
9
|
+
"edit": "Editar",
|
|
10
|
+
"create": "Crear",
|
|
11
|
+
"update": "Actualizar",
|
|
12
|
+
"search": "Buscar",
|
|
13
|
+
"filter": "Filtrar",
|
|
14
|
+
"clear": "Limpiar",
|
|
15
|
+
"close": "Cerrar",
|
|
16
|
+
"back": "Atrás",
|
|
17
|
+
"next": "Siguiente",
|
|
18
|
+
"previous": "Anterior",
|
|
19
|
+
"submit": "Enviar",
|
|
20
|
+
"confirm": "Confirmar"
|
|
21
|
+
},
|
|
22
|
+
"nav": {
|
|
23
|
+
"home": "Inicio",
|
|
24
|
+
"about": "Acerca de",
|
|
25
|
+
"contact": "Contacto"
|
|
26
|
+
},
|
|
27
|
+
"home": {
|
|
28
|
+
"title": "Bienvenido a {{PROJECT_NAME}}",
|
|
29
|
+
"description": "Un monorepo profesional full-stack con Next.js, Fastify y pnpm workspaces"
|
|
30
|
+
},
|
|
31
|
+
"footer": {
|
|
32
|
+
"copyright": "© {year} {{PROJECT_NAME}}. Todos los derechos reservados."
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { NextConfig } from 'next';
|
|
2
|
+
import createNextIntlPlugin from 'next-intl/plugin';
|
|
3
|
+
|
|
4
|
+
const withNextIntl = createNextIntlPlugin('./i18n/request.ts');
|
|
5
|
+
|
|
6
|
+
const nextConfig: NextConfig = {
|
|
7
|
+
async headers() {
|
|
8
|
+
return [
|
|
9
|
+
{
|
|
10
|
+
source: '/:path*',
|
|
11
|
+
headers: [
|
|
12
|
+
{
|
|
13
|
+
key: 'X-DNS-Prefetch-Control',
|
|
14
|
+
value: 'on',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
key: 'X-Frame-Options',
|
|
18
|
+
value: 'SAMEORIGIN',
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
key: 'X-Content-Type-Options',
|
|
22
|
+
value: 'nosniff',
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
key: 'Referrer-Policy',
|
|
26
|
+
value: 'origin-when-cross-origin',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
key: 'Permissions-Policy',
|
|
30
|
+
value: 'camera=(), microphone=(), geolocation=()',
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
},
|
|
34
|
+
];
|
|
35
|
+
},
|
|
36
|
+
poweredByHeader: false,
|
|
37
|
+
reactStrictMode: true,
|
|
38
|
+
logging: {
|
|
39
|
+
fetches: {
|
|
40
|
+
fullUrl: true,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
experimental: {
|
|
44
|
+
serverActions: {
|
|
45
|
+
bodySizeLimit: '2mb',
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
export default withNextIntl(nextConfig);
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@{{PROJECT_NAME}}/web",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"scripts": {
|
|
6
|
+
"dev": "next dev",
|
|
7
|
+
"build": "next build",
|
|
8
|
+
"start": "next start",
|
|
9
|
+
"lint": "eslint ."
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"clsx": "^2.1.1",
|
|
13
|
+
"next": "^16.1.1",
|
|
14
|
+
"next-intl": "^4.7.0",
|
|
15
|
+
"react": "^19.0.0",
|
|
16
|
+
"react-dom": "^19.0.0",
|
|
17
|
+
"tailwind-merge": "^3.4.0",
|
|
18
|
+
"@{{PROJECT_NAME}}/shared": "workspace:*"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@tailwindcss/postcss": "^4.1.14",
|
|
22
|
+
"@types/node": "^22.10.5",
|
|
23
|
+
"@types/react": "^19.0.9",
|
|
24
|
+
"@types/react-dom": "^19.0.4",
|
|
25
|
+
"eslint": "^9.18.0",
|
|
26
|
+
"eslint-config-next": "^16.1.1",
|
|
27
|
+
"prettier": "^3.4.2",
|
|
28
|
+
"tailwindcss": "^4.1.14",
|
|
29
|
+
"typescript": "^5.7.3"
|
|
30
|
+
},
|
|
31
|
+
"engines": {
|
|
32
|
+
"node": ">=20.0.0"
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import createMiddleware from 'next-intl/middleware';
|
|
2
|
+
import { NextRequest } from 'next/server';
|
|
3
|
+
import { locales, defaultLocale } from './i18n/config';
|
|
4
|
+
|
|
5
|
+
const intlMiddleware = createMiddleware({
|
|
6
|
+
locales,
|
|
7
|
+
defaultLocale,
|
|
8
|
+
localePrefix: 'always',
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
export default async function middleware(request: NextRequest) {
|
|
12
|
+
return intlMiddleware(request);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const config = {
|
|
16
|
+
matcher: ['/', '/(es|en)/:path*', '/((?!_next|_vercel|.*\\..*).*)'],
|
|
17
|
+
};
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"lib": ["dom", "dom.iterable", "esnext"],
|
|
5
|
+
"allowJs": true,
|
|
6
|
+
"skipLibCheck": true,
|
|
7
|
+
"strict": true,
|
|
8
|
+
"noEmit": true,
|
|
9
|
+
"esModuleInterop": true,
|
|
10
|
+
"module": "esnext",
|
|
11
|
+
"moduleResolution": "bundler",
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"jsx": "react-jsx",
|
|
15
|
+
"incremental": true,
|
|
16
|
+
"plugins": [
|
|
17
|
+
{
|
|
18
|
+
"name": "next"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"paths": {
|
|
22
|
+
"@/*": ["./*"]
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts", ".next/dev/types/**/*.ts"],
|
|
26
|
+
"exclude": ["node_modules"]
|
|
27
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Documentation
|
|
2
|
+
|
|
3
|
+
This folder contains project documentation.
|
|
4
|
+
|
|
5
|
+
## Suggested Documents
|
|
6
|
+
|
|
7
|
+
- **API.md** - API endpoints documentation
|
|
8
|
+
- **ARCHITECTURE.md** - System architecture overview
|
|
9
|
+
- **DEPLOYMENT.md** - Deployment guides
|
|
10
|
+
- **TROUBLESHOOTING.md** - Common issues and solutions
|
|
11
|
+
- **CHANGELOG.md** - Version history and changes
|
|
12
|
+
|
|
13
|
+
Feel free to add any documentation that helps team members understand and work with the project.
|