create-next-pro-cli 0.1.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.
Files changed (106) hide show
  1. package/.vscode/settings.json +3 -0
  2. package/CODE_OF_CONDUCT.md +33 -0
  3. package/CONTRIBUTING.md +44 -0
  4. package/FONCTIONALITY.md +25 -0
  5. package/README.md +292 -0
  6. package/bin.ts +2 -0
  7. package/bun.lock +27 -0
  8. package/create-next-pro-completion.sh +36 -0
  9. package/install.sh +18 -0
  10. package/package.json +32 -0
  11. package/public/logo.svg +76 -0
  12. package/src/index.ts +511 -0
  13. package/src/scaffold-dev.ts +89 -0
  14. package/src/scaffold.ts +70 -0
  15. package/templates/Component/Component.tsx +13 -0
  16. package/templates/Component/component.json +4 -0
  17. package/templates/Page/default.tsx +0 -0
  18. package/templates/Page/error.tsx +38 -0
  19. package/templates/Page/global-error.tsx +0 -0
  20. package/templates/Page/layout.tsx +0 -0
  21. package/templates/Page/loading.tsx +17 -0
  22. package/templates/Page/not-found.tsx +0 -0
  23. package/templates/Page/page-ui.tsx +22 -0
  24. package/templates/Page/page.json +4 -0
  25. package/templates/Page/page.tsx +24 -0
  26. package/templates/Page/route.ts +0 -0
  27. package/templates/Page/template.tsx +0 -0
  28. package/templates/Projects/default/README.md +36 -0
  29. package/templates/Projects/default/eslint.config.mjs +16 -0
  30. package/templates/Projects/default/messages/en/_global_ui.json +30 -0
  31. package/templates/Projects/default/messages/en/_home.json +4 -0
  32. package/templates/Projects/default/messages/en/dashboard.json +14 -0
  33. package/templates/Projects/default/messages/en/login.json +7 -0
  34. package/templates/Projects/default/messages/en/register.json +7 -0
  35. package/templates/Projects/default/messages/en/settings.json +4 -0
  36. package/templates/Projects/default/messages/en/user_info.json +4 -0
  37. package/templates/Projects/default/messages/en.ts +4 -0
  38. package/templates/Projects/default/messages/fr/_global_ui.json +30 -0
  39. package/templates/Projects/default/messages/fr/_home.json +4 -0
  40. package/templates/Projects/default/messages/fr/dashboard.json +14 -0
  41. package/templates/Projects/default/messages/fr/login.json +7 -0
  42. package/templates/Projects/default/messages/fr/register.json +7 -0
  43. package/templates/Projects/default/messages/fr/settings.json +4 -0
  44. package/templates/Projects/default/messages/fr/user_info.json +4 -0
  45. package/templates/Projects/default/messages/fr.ts +4 -0
  46. package/templates/Projects/default/messages/getMergedMessages.ts +31 -0
  47. package/templates/Projects/default/middleware.ts +11 -0
  48. package/templates/Projects/default/next.config.ts +12 -0
  49. package/templates/Projects/default/package.json +32 -0
  50. package/templates/Projects/default/postcss.config.mjs +5 -0
  51. package/templates/Projects/default/public/cnp-logo.ico +0 -0
  52. package/templates/Projects/default/public/cnp-logo.png +0 -0
  53. package/templates/Projects/default/public/cnp-logo.svg +76 -0
  54. package/templates/Projects/default/public/file.svg +1 -0
  55. package/templates/Projects/default/public/globe.svg +1 -0
  56. package/templates/Projects/default/public/next.svg +1 -0
  57. package/templates/Projects/default/public/vercel.svg +1 -0
  58. package/templates/Projects/default/public/window.svg +1 -0
  59. package/templates/Projects/default/src/app/[locale]/(public)/_home/loading.tsx +1 -0
  60. package/templates/Projects/default/src/app/[locale]/(public)/_home/page.tsx +16 -0
  61. package/templates/Projects/default/src/app/[locale]/(public)/layout.tsx +11 -0
  62. package/templates/Projects/default/src/app/[locale]/(public)/login/page.tsx +19 -0
  63. package/templates/Projects/default/src/app/[locale]/(public)/register/page.tsx +23 -0
  64. package/templates/Projects/default/src/app/[locale]/(user)/dashboard/error.tsx +38 -0
  65. package/templates/Projects/default/src/app/[locale]/(user)/dashboard/loading.tsx +17 -0
  66. package/templates/Projects/default/src/app/[locale]/(user)/dashboard/page.tsx +12 -0
  67. package/templates/Projects/default/src/app/[locale]/(user)/layout.tsx +12 -0
  68. package/templates/Projects/default/src/app/[locale]/(user)/settings/loading.tsx +17 -0
  69. package/templates/Projects/default/src/app/[locale]/(user)/settings/page.tsx +12 -0
  70. package/templates/Projects/default/src/app/[locale]/(user)/user_info/loading.tsx +17 -0
  71. package/templates/Projects/default/src/app/[locale]/(user)/user_info/page.tsx +12 -0
  72. package/templates/Projects/default/src/app/[locale]/layout.tsx +32 -0
  73. package/templates/Projects/default/src/app/[locale]/loading.tsx +17 -0
  74. package/templates/Projects/default/src/app/[locale]/not-found.tsx +22 -0
  75. package/templates/Projects/default/src/app/[locale]/page.tsx +116 -0
  76. package/templates/Projects/default/src/app/api/auth/[...nextauth]/route.ts +81 -0
  77. package/templates/Projects/default/src/app/api/auth/[...nextauth].ts +0 -0
  78. package/templates/Projects/default/src/app/api/auth/post-login/route.ts +27 -0
  79. package/templates/Projects/default/src/app/api/me/route.ts +15 -0
  80. package/templates/Projects/default/src/app/favicon.ico +0 -0
  81. package/templates/Projects/default/src/app/layout.tsx +11 -0
  82. package/templates/Projects/default/src/app/not-found.tsx +17 -0
  83. package/templates/Projects/default/src/app/page.tsx +6 -0
  84. package/templates/Projects/default/src/app/sitemap.ts +27 -0
  85. package/templates/Projects/default/src/app/styles/globals.css +26 -0
  86. package/templates/Projects/default/src/app/ui/dashboard/MainDashboard.tsx +21 -0
  87. package/templates/Projects/default/src/app/ui/dashboard/StatsCard.tsx +14 -0
  88. package/templates/Projects/default/src/app/ui/dashboard/WelcomeCard.tsx +10 -0
  89. package/templates/Projects/default/src/auth.config.ts +0 -0
  90. package/templates/Projects/default/src/config.ts +4 -0
  91. package/templates/Projects/default/src/lib/auth/isConnected.ts +16 -0
  92. package/templates/Projects/default/src/lib/i18n/navigation.ts +19 -0
  93. package/templates/Projects/default/src/lib/i18n/request.ts +31 -0
  94. package/templates/Projects/default/src/lib/i18n/routing.ts +20 -0
  95. package/templates/Projects/default/src/ui/_global/BackButton.tsx +15 -0
  96. package/templates/Projects/default/src/ui/_global/GlobalHeader.tsx +34 -0
  97. package/templates/Projects/default/src/ui/_global/GlobalMain.tsx +15 -0
  98. package/templates/Projects/default/src/ui/_global/LocaleSwitcher.tsx +38 -0
  99. package/templates/Projects/default/src/ui/_global/PublicNav.tsx +30 -0
  100. package/templates/Projects/default/src/ui/_global/UserNav.tsx +32 -0
  101. package/templates/Projects/default/src/ui/dashboard/StatsCard.tsx +14 -0
  102. package/templates/Projects/default/src/ui/dashboard/WelcomeCard.tsx +10 -0
  103. package/templates/Projects/default/src/ui/dashboard/page.tsx +22 -0
  104. package/templates/Projects/default/tailwind.config.ts +1 -0
  105. package/templates/Projects/default/tsconfig.json +34 -0
  106. package/tsconfig.json +27 -0
@@ -0,0 +1,16 @@
1
+ import { cookies } from "next/headers";
2
+ import { verify } from "jsonwebtoken";
3
+
4
+ export async function isConnected(): Promise<boolean> {
5
+ const cookieStore = await cookies();
6
+ const appToken = cookieStore.get("app_token")?.value;
7
+ if (appToken) {
8
+ try {
9
+ verify(appToken, process.env.APP_JWT_SECRET!);
10
+ return true;
11
+ } catch {
12
+ return false;
13
+ }
14
+ }
15
+ return false;
16
+ }
@@ -0,0 +1,19 @@
1
+ // lib/i18n/navigation.ts
2
+ import { createNavigation } from "next-intl/navigation";
3
+ import { routing } from "./routing";
4
+
5
+ // Lightweight wrappers around Next.js' navigation
6
+ // APIs that consider the routing configuration
7
+ export const { Link, redirect, usePathname, useRouter, getPathname } =
8
+ createNavigation(routing);
9
+ // This file sets up navigation for internationalization (i18n) in a Next.js application
10
+ // It uses the createLocalizedPathnamesNavigation function from next-intl/navigation
11
+ // to create localized links and navigation functions
12
+ // The locales and defaultLocale are imported from the routing module
13
+ // This allows the application to support multiple languages, such as English and French
14
+ // The Link component can be used to create links that respect the current locale
15
+ // The redirect function can be used to redirect users to the appropriate locale
16
+ // The usePathname and useRouter hooks can be used to access the current pathname and router
17
+ // This setup is essential for providing a seamless navigation experience in a multilingual application
18
+ // Make sure to import this module in your application to enable i18n navigation
19
+ // You can also customize the Link component to add additional props or styles
@@ -0,0 +1,31 @@
1
+ // lib/i18n/request.ts
2
+ import { getRequestConfig } from "next-intl/server";
3
+ import { hasLocale } from "next-intl";
4
+ import { routing } from "./routing";
5
+
6
+ export default getRequestConfig(async ({ requestLocale }) => {
7
+ //console.log("Requesting locale... :", requestLocale);
8
+ // Typically corresponds to the `[locale]` segment
9
+ //console.log("Routing :", routing);
10
+ const requested = await requestLocale;
11
+ //console.log(`Requested locale: "${requested}"`);
12
+ const locale = hasLocale(routing.locales, requested)
13
+ ? requested
14
+ : routing.defaultLocale;
15
+
16
+ //console.log(`Locale requested: "${locale}"`);
17
+
18
+ return {
19
+ locale,
20
+ messages: (await import(`@/../messages/${locale}.ts`)).default,
21
+ };
22
+ });
23
+
24
+ // This file is used to configure internationalization (i18n) for the Next.js application
25
+ // It imports the getRequestConfig function from next-intl/server to set up locale-specific messages
26
+ // The messages are loaded dynamically based on the requested locale
27
+ // The locales and defaultLocale are imported from the routing module
28
+ // This allows the application to support multiple languages, such as English and French
29
+ // The messages are expected to be in JSON format and located in the messages directory
30
+ // This setup is essential for providing localized content to users based on their language preferences
31
+ // Make sure to create the necessary message files for each locale in the specified directory
@@ -0,0 +1,20 @@
1
+ // lib/i18n/routing.ts
2
+ import { defineRouting } from "next-intl/routing";
3
+
4
+ export const routing = defineRouting({
5
+ // A list of all locales that are supported
6
+ locales: ["en", "fr"],
7
+ localeDetection: true,
8
+ localeCookie: true,
9
+
10
+ // Used when no locale matches
11
+ defaultLocale: "en",
12
+ });
13
+ // This file defines the routing configuration for internationalization (i18n) in a Next.js application
14
+ // It uses the defineRouting function from next-intl/routing to set up the locales and default locale
15
+ // The locales array specifies the supported languages, such as English and German
16
+ // The defaultLocale is set to English, which will be used when no specific locale is requested
17
+ // The pathnames object maps the root path ("/") to itself and provides a localized version
18
+ // for the "/pathnames" route in German, which is mapped to "/pfadnamen"
19
+ // This setup allows the application to handle different languages and provide localized content
20
+ // Make sure to import this routing configuration in your application to enable i18n routing
@@ -0,0 +1,15 @@
1
+ "use client"; // DO NOT FORGET , this is a client component.
2
+ import { useRouter } from "next/navigation";
3
+
4
+ export default function BackButton({ className = "" }: { className?: string }) {
5
+ const router = useRouter();
6
+ return (
7
+ <button
8
+ type="button"
9
+ onClick={() => router.back()}
10
+ className={`inline-flex items-center gap-2 px-3 py-1.5 rounded border border-gray-300 bg-white text-gray-700 hover:bg-gray-100 transition ${className}`}
11
+ >
12
+ <span aria-hidden="true">←</span> Retour
13
+ </button>
14
+ );
15
+ }
@@ -0,0 +1,34 @@
1
+ import Image from "next/image";
2
+ import UserNav from "@/ui/_global/UserNav";
3
+ import LocaleSwitcher from "@/ui/_global/LocaleSwitcher";
4
+ import PublicNav from "@/ui/_global/PublicNav";
5
+
6
+ export default function GlobalHeader({
7
+ isConnected,
8
+ }: {
9
+ isConnected: boolean;
10
+ }) {
11
+ return (
12
+ <header className="sticky top-0 z-30 w-full border-b bg-white/80 backdrop-blur supports-[backdrop-filter]:bg-white/60 shadow-sm">
13
+ <div className="mx-auto flex h-16 max-w-6xl items-center justify-between px-6">
14
+ <div className="flex items-center gap-3">
15
+ {/* Logo Next.js SVG */}
16
+ <Image
17
+ src="/cnp-logo.svg"
18
+ alt="Logo"
19
+ width={63}
20
+ height={63}
21
+ className="mr-2"
22
+ />
23
+ <span className="text-lg font-semibold tracking-tight select-none">
24
+ Create Next Pro
25
+ </span>
26
+ </div>
27
+ <nav className="flex items-center gap-4">
28
+ {isConnected ? <UserNav /> : <PublicNav />}
29
+ <LocaleSwitcher />
30
+ </nav>
31
+ </div>
32
+ </header>
33
+ );
34
+ }
@@ -0,0 +1,15 @@
1
+ import React from "react";
2
+
3
+ export default function GlobalMain({
4
+ children,
5
+ }: {
6
+ children: React.ReactNode;
7
+ }) {
8
+ return (
9
+ <main className="min-h-screen bg-neutral-50 font-sans text-gray-900">
10
+ <section className="mx-auto w-full max-w-3xl py-16 px-6">
11
+ {children}
12
+ </section>
13
+ </main>
14
+ );
15
+ }
@@ -0,0 +1,38 @@
1
+ "use client"; // DO NOT FORGET , this is a client component.
2
+ import { useRouter, usePathname } from "next/navigation";
3
+ import { useParams } from "next/navigation";
4
+
5
+ const locales = [
6
+ { code: "fr", label: "Français" },
7
+ { code: "en", label: "English" },
8
+ ];
9
+
10
+ export default function LocaleSwitcher() {
11
+ const router = useRouter();
12
+ const pathname = usePathname();
13
+ const params = useParams();
14
+ const currentLocale = params?.locale || "fr";
15
+
16
+ const handleChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
17
+ const newLocale = e.target.value;
18
+ if (newLocale === currentLocale) return;
19
+ // Replace locale in pathname
20
+ const newPath = pathname.replace(`/${currentLocale}`, `/${newLocale}`);
21
+ router.push(newPath);
22
+ };
23
+
24
+ return (
25
+ <select
26
+ className="ml-2 border rounded px-2 py-1 text-sm bg-white"
27
+ value={currentLocale}
28
+ onChange={handleChange}
29
+ aria-label="Select language"
30
+ >
31
+ {locales.map((l) => (
32
+ <option key={l.code} value={l.code}>
33
+ {l.label}
34
+ </option>
35
+ ))}
36
+ </select>
37
+ );
38
+ }
@@ -0,0 +1,30 @@
1
+ "use client"; // DO NOT FORGET , this is a client component.
2
+ import { Link } from "@/lib/i18n/navigation";
3
+ import { useTranslations } from "next-intl";
4
+
5
+ const navLinks = [
6
+ { href: "/", labelKey: "public_nav.links.home" },
7
+ { href: "/login", labelKey: "public_nav.links.login" },
8
+ { href: "/register", labelKey: "public_nav.links.register" },
9
+ ];
10
+
11
+ const PublicNav = () => {
12
+ const t = useTranslations("_global_ui");
13
+ return (
14
+ <nav aria-label="Public navigation">
15
+ <ul className="flex gap-2 md:gap-4">
16
+ {navLinks.map((link) => (
17
+ <li key={link.href}>
18
+ <Link
19
+ href={link.href}
20
+ className="inline-block rounded px-3 py-1.5 text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500"
21
+ >
22
+ {t(link.labelKey)}
23
+ </Link>
24
+ </li>
25
+ ))}
26
+ </ul>
27
+ </nav>
28
+ );
29
+ };
30
+ export default PublicNav;
@@ -0,0 +1,32 @@
1
+ "use client"; // DO NOT FORGET , this is a client component.
2
+ import { Link } from "@/lib/i18n/navigation";
3
+ import { useTranslations } from "next-intl";
4
+
5
+ const navLinks = [
6
+ { href: "/dashboard", labelKey: "user_nav.links.dashboard" },
7
+ { href: "/settings", labelKey: "user_nav.links.settings" },
8
+ { href: "/user_info", labelKey: "user_nav.links.user_info" },
9
+ { href: "/", labelKey: "user_nav.links.home" },
10
+ ];
11
+
12
+ const UserNav = () => {
13
+ const t = useTranslations("_global_ui");
14
+ return (
15
+ <nav aria-label="User navigation">
16
+ <ul className="flex gap-2 md:gap-4">
17
+ {navLinks.map((link) => (
18
+ <li key={link.href}>
19
+ <Link
20
+ href={link.href}
21
+ className="inline-block rounded px-3 py-1.5 text-sm font-medium text-gray-700 hover:text-blue-600 hover:bg-blue-50 transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-blue-500"
22
+ >
23
+ {t(link.labelKey)}
24
+ </Link>
25
+ </li>
26
+ ))}
27
+ </ul>
28
+ </nav>
29
+ );
30
+ };
31
+
32
+ export default UserNav;
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+
3
+ export default function StatsCard({ t }: { t: (key: string) => string }) {
4
+ return (
5
+ <div className="rounded border bg-white p-6 shadow-sm">
6
+ <h2 className="text-lg font-semibold mb-2">Statistiques</h2>
7
+ <ul className="text-sm text-gray-600 space-y-1">
8
+ <li>• {t("widgets.stats.views")}: 123</li>
9
+ <li>• {t("widgets.stats.likes")}: 45</li>
10
+ <li>• {t("widgets.stats.comments")}: 7</li>
11
+ </ul>
12
+ </div>
13
+ );
14
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+
3
+ export default function WelcomeCard({ t }: { t: (key: string) => string }) {
4
+ return (
5
+ <div className="rounded border bg-white p-6 shadow-sm">
6
+ <h2 className="text-lg font-semibold mb-2">{t("widgets.welcome")}</h2>
7
+ <p className="text-gray-600">{t("widgets.description")}</p>
8
+ </div>
9
+ );
10
+ }
@@ -0,0 +1,22 @@
1
+ ("");
2
+ import { useTranslations } from "next-intl";
3
+ import BackButton from "@/ui/_global/BackButton";
4
+ import WelcomeCard from "@/ui/dashboard/WelcomeCard";
5
+ import StatsCard from "@/ui/dashboard/StatsCard";
6
+
7
+ export default function Dashboard() {
8
+ const t = useTranslations("dashboard");
9
+ return (
10
+ <>
11
+ <div className="flex items-center justify-between mb-6">
12
+ <h1 className="text-2xl font-bold">{t("title")}</h1>
13
+ <BackButton />
14
+ </div>
15
+ <p className="text-muted mb-8">{t("description")}</p>
16
+ <section className="grid grid-cols-1 md:grid-cols-2 gap-6">
17
+ <WelcomeCard t={t} />
18
+ <StatsCard t={t} />
19
+ </section>
20
+ </>
21
+ );
22
+ }
@@ -0,0 +1 @@
1
+ // tailwind.config.ts
@@ -0,0 +1,34 @@
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": "preserve",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./src/*"]
23
+ }
24
+ },
25
+ "include": [
26
+ "next-env.d.ts",
27
+ "**/*.ts",
28
+ "**/*.tsx",
29
+ ".next/types/**/*.ts"
30
+ /* "src/app/not-found.tsx.save",
31
+ "src/app/layout.tsx.save" */
32
+ ],
33
+ "exclude": ["node_modules"]
34
+ }
package/tsconfig.json ADDED
@@ -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": "preserve",
15
+ "incremental": true,
16
+ "plugins": [
17
+ {
18
+ "name": "next"
19
+ }
20
+ ],
21
+ "paths": {
22
+ "@/*": ["./src/*"]
23
+ }
24
+ },
25
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26
+ "exclude": ["node_modules"]
27
+ }