@prmvx/frontend-forge 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.
- package/LICENSE +21 -0
- package/README.md +224 -0
- package/dist/cli.js +662 -0
- package/dist/cli.js.map +1 -0
- package/dist/templates/architectures/next/enterprise/src/components/common/Button.tsx +17 -0
- package/dist/templates/architectures/next/enterprise/src/components/home/HomeView.tsx +41 -0
- package/dist/templates/architectures/next/enterprise/src/components/layout/Footer.tsx +9 -0
- package/dist/templates/architectures/next/enterprise/src/components/layout/Header.tsx +19 -0
- package/dist/templates/architectures/next/enterprise/src/config/env.ts +3 -0
- package/dist/templates/architectures/next/enterprise/src/constants/routes.ts +4 -0
- package/dist/templates/architectures/next/enterprise/src/features/dashboard/components/DashboardSummary.tsx +22 -0
- package/dist/templates/architectures/next/enterprise/src/features/dashboard/hooks/useDashboard.ts +18 -0
- package/dist/templates/architectures/next/enterprise/src/features/dashboard/services/dashboard-api.ts +22 -0
- package/dist/templates/architectures/next/enterprise/src/features/dashboard/types/index.ts +4 -0
- package/dist/templates/architectures/next/enterprise/src/hooks/useDebounce.ts +14 -0
- package/dist/templates/architectures/next/enterprise/src/hooks/useToggle.ts +15 -0
- package/dist/templates/architectures/next/enterprise/src/providers/index.tsx +17 -0
- package/dist/templates/architectures/next/enterprise/src/providers/theme-provider.tsx +11 -0
- package/dist/templates/architectures/next/enterprise/src/services/api.ts +22 -0
- package/dist/templates/architectures/next/enterprise/src/store/app-store.tsx +33 -0
- package/dist/templates/architectures/next/enterprise/src/types/user.ts +5 -0
- package/dist/templates/architectures/next/enterprise/src/utils/cn.ts +3 -0
- package/dist/templates/architectures/next/enterprise/src/utils/formatDate.ts +7 -0
- package/dist/templates/architectures/next/feature/src/config/env.ts +3 -0
- package/dist/templates/architectures/next/feature/src/features/home/components/HomeHero.tsx +38 -0
- package/dist/templates/architectures/next/feature/src/features/home/components/HomePage.tsx +19 -0
- package/dist/templates/architectures/next/feature/src/features/home/constants/routes.ts +4 -0
- package/dist/templates/architectures/next/feature/src/features/home/hooks/useHome.ts +18 -0
- package/dist/templates/architectures/next/feature/src/features/home/services/home-api.ts +22 -0
- package/dist/templates/architectures/next/feature/src/features/home/types/index.ts +4 -0
- package/dist/templates/architectures/next/feature/src/features/profile/components/ProfileCard.tsx +19 -0
- package/dist/templates/architectures/next/feature/src/features/profile/hooks/useProfile.ts +18 -0
- package/dist/templates/architectures/next/feature/src/features/profile/services/profile-api.ts +22 -0
- package/dist/templates/architectures/next/feature/src/features/profile/types/index.ts +5 -0
- package/dist/templates/architectures/next/feature/src/shared/components/common/Button.tsx +17 -0
- package/dist/templates/architectures/next/feature/src/shared/components/layout/Footer.tsx +9 -0
- package/dist/templates/architectures/next/feature/src/shared/components/layout/Header.tsx +19 -0
- package/dist/templates/architectures/next/feature/src/shared/hooks/useDebounce.ts +14 -0
- package/dist/templates/architectures/next/feature/src/shared/hooks/useToggle.ts +15 -0
- package/dist/templates/architectures/next/feature/src/shared/providers/index.tsx +8 -0
- package/dist/templates/architectures/next/feature/src/shared/providers/theme-provider.tsx +7 -0
- package/dist/templates/architectures/next/feature/src/shared/utils/cn.ts +3 -0
- package/dist/templates/architectures/next/feature/src/shared/utils/formatDate.ts +7 -0
- package/dist/templates/architectures/next/standard/src/components/common/Button.tsx +17 -0
- package/dist/templates/architectures/next/standard/src/components/home/HomeView.tsx +53 -0
- package/dist/templates/architectures/next/standard/src/components/layout/Footer.tsx +9 -0
- package/dist/templates/architectures/next/standard/src/components/layout/Header.tsx +19 -0
- package/dist/templates/architectures/next/standard/src/config/env.ts +3 -0
- package/dist/templates/architectures/next/standard/src/constants/routes.ts +4 -0
- package/dist/templates/architectures/next/standard/src/hooks/useDebounce.ts +14 -0
- package/dist/templates/architectures/next/standard/src/hooks/useToggle.ts +15 -0
- package/dist/templates/architectures/next/standard/src/providers/index.tsx +12 -0
- package/dist/templates/architectures/next/standard/src/providers/theme-provider.tsx +11 -0
- package/dist/templates/architectures/next/standard/src/services/api.ts +22 -0
- package/dist/templates/architectures/next/standard/src/types/user.ts +5 -0
- package/dist/templates/architectures/next/standard/src/utils/cn.ts +3 -0
- package/dist/templates/architectures/next/standard/src/utils/formatDate.ts +7 -0
- package/dist/templates/modules/axios/module.ts +7 -0
- package/dist/templates/modules/core/module.ts +5 -0
- package/dist/templates/modules/core/src/components/common/Button.tsx +12 -0
- package/dist/templates/modules/core/src/components/layout/Header.tsx +7 -0
- package/dist/templates/modules/core/src/config/env.ts +3 -0
- package/dist/templates/modules/core/src/constants/index.ts +1 -0
- package/dist/templates/modules/core/src/constants/routes.ts +3 -0
- package/dist/templates/modules/core/src/hooks/index.ts +1 -0
- package/dist/templates/modules/core/src/hooks/useToggle.ts +13 -0
- package/dist/templates/modules/core/src/providers/index.tsx +9 -0
- package/dist/templates/modules/core/src/services/api.ts +5 -0
- package/dist/templates/modules/core/src/utils/cn.ts +3 -0
- package/dist/templates/modules/core/src/utils/index.ts +1 -0
- package/dist/templates/modules/zustand/module.ts +7 -0
- package/package.json +70 -0
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Link from "next/link";
|
|
2
|
+
import { Button } from "@/shared/components/common/Button";
|
|
3
|
+
import { HOME_ROUTES } from "@/features/home/constants/routes";
|
|
4
|
+
|
|
5
|
+
export function Header() {
|
|
6
|
+
return (
|
|
7
|
+
<header className="flex items-center justify-between border-b px-6 py-4">
|
|
8
|
+
<Link href={HOME_ROUTES.HOME} className="text-lg font-semibold">
|
|
9
|
+
Feature App
|
|
10
|
+
</Link>
|
|
11
|
+
<nav className="flex items-center gap-3">
|
|
12
|
+
<Link href={HOME_ROUTES.PROFILE} className="text-sm text-zinc-600">
|
|
13
|
+
Profile
|
|
14
|
+
</Link>
|
|
15
|
+
<Button>Explore</Button>
|
|
16
|
+
</nav>
|
|
17
|
+
</header>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
|
|
5
|
+
export function useDebounce<T>(value: T, delay = 300) {
|
|
6
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay);
|
|
10
|
+
return () => clearTimeout(timer);
|
|
11
|
+
}, [value, delay]);
|
|
12
|
+
|
|
13
|
+
return debouncedValue;
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
|
|
5
|
+
export function useToggle(defaultValue = false) {
|
|
6
|
+
const [value, setValue] = useState(defaultValue);
|
|
7
|
+
|
|
8
|
+
const toggle = () => setValue((prev) => !prev);
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
value,
|
|
12
|
+
toggle,
|
|
13
|
+
setValue,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { cn } from "@/utils/cn";
|
|
2
|
+
|
|
3
|
+
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
4
|
+
|
|
5
|
+
export function Button({ children, className, ...props }: ButtonProps) {
|
|
6
|
+
return (
|
|
7
|
+
<button
|
|
8
|
+
{...props}
|
|
9
|
+
className={cn(
|
|
10
|
+
"rounded-md bg-zinc-900 px-4 py-2 text-sm font-medium text-white transition hover:bg-zinc-700",
|
|
11
|
+
className
|
|
12
|
+
)}
|
|
13
|
+
>
|
|
14
|
+
{children}
|
|
15
|
+
</button>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
import { Header } from "@/components/layout/Header";
|
|
5
|
+
import { Footer } from "@/components/layout/Footer";
|
|
6
|
+
import { Button } from "@/components/common/Button";
|
|
7
|
+
import { useToggle } from "@/hooks/useToggle";
|
|
8
|
+
import { useDebounce } from "@/hooks/useDebounce";
|
|
9
|
+
import { formatDate } from "@/utils/formatDate";
|
|
10
|
+
|
|
11
|
+
export function HomeView() {
|
|
12
|
+
const { value, toggle } = useToggle();
|
|
13
|
+
const [query, setQuery] = useState("architecture");
|
|
14
|
+
const debouncedQuery = useDebounce(query);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<div className="flex min-h-screen flex-col">
|
|
18
|
+
<Header />
|
|
19
|
+
<main className="mx-auto flex w-full max-w-3xl flex-1 flex-col gap-6 px-6 py-10">
|
|
20
|
+
<section className="space-y-2">
|
|
21
|
+
<p className="text-sm uppercase tracking-wide text-zinc-500">
|
|
22
|
+
Standard Architecture
|
|
23
|
+
</p>
|
|
24
|
+
<h1 className="text-3xl font-bold">A simple, connected starter</h1>
|
|
25
|
+
<p className="text-zinc-600">
|
|
26
|
+
Components, hooks, services, and utilities work together from day
|
|
27
|
+
one. Today is {formatDate(new Date())}.
|
|
28
|
+
</p>
|
|
29
|
+
</section>
|
|
30
|
+
|
|
31
|
+
<section className="rounded-lg border p-4">
|
|
32
|
+
<h2 className="mb-2 font-medium">Hook demo</h2>
|
|
33
|
+
<p className="mb-3 text-sm text-zinc-600">
|
|
34
|
+
Toggle state: {value ? "On" : "Off"}
|
|
35
|
+
</p>
|
|
36
|
+
<Button onClick={toggle}>Toggle with useToggle</Button>
|
|
37
|
+
</section>
|
|
38
|
+
|
|
39
|
+
<section className="rounded-lg border p-4">
|
|
40
|
+
<h2 className="mb-2 font-medium">Debounce demo</h2>
|
|
41
|
+
<input
|
|
42
|
+
className="mb-2 w-full rounded-md border px-3 py-2"
|
|
43
|
+
value={query}
|
|
44
|
+
onChange={(event) => setQuery(event.target.value)}
|
|
45
|
+
placeholder="Type to debounce"
|
|
46
|
+
/>
|
|
47
|
+
<p className="text-sm text-zinc-600">Debounced: {debouncedQuery}</p>
|
|
48
|
+
</section>
|
|
49
|
+
</main>
|
|
50
|
+
<Footer />
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import Link from "next/link";
|
|
2
|
+
import { Button } from "@/components/common/Button";
|
|
3
|
+
import { ROUTES } from "@/constants/routes";
|
|
4
|
+
|
|
5
|
+
export function Header() {
|
|
6
|
+
return (
|
|
7
|
+
<header className="flex items-center justify-between border-b px-6 py-4">
|
|
8
|
+
<Link href={ROUTES.HOME} className="text-lg font-semibold">
|
|
9
|
+
Frontend Init
|
|
10
|
+
</Link>
|
|
11
|
+
<nav className="flex items-center gap-3">
|
|
12
|
+
<Link href={ROUTES.ABOUT} className="text-sm text-zinc-600">
|
|
13
|
+
About
|
|
14
|
+
</Link>
|
|
15
|
+
<Button>Get Started</Button>
|
|
16
|
+
</nav>
|
|
17
|
+
</header>
|
|
18
|
+
);
|
|
19
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useEffect, useState } from "react";
|
|
4
|
+
|
|
5
|
+
export function useDebounce<T>(value: T, delay = 300) {
|
|
6
|
+
const [debouncedValue, setDebouncedValue] = useState(value);
|
|
7
|
+
|
|
8
|
+
useEffect(() => {
|
|
9
|
+
const timer = setTimeout(() => setDebouncedValue(value), delay);
|
|
10
|
+
return () => clearTimeout(timer);
|
|
11
|
+
}, [value, delay]);
|
|
12
|
+
|
|
13
|
+
return debouncedValue;
|
|
14
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useState } from "react";
|
|
4
|
+
|
|
5
|
+
export function useToggle(defaultValue = false) {
|
|
6
|
+
const [value, setValue] = useState(defaultValue);
|
|
7
|
+
|
|
8
|
+
const toggle = () => setValue((prev) => !prev);
|
|
9
|
+
|
|
10
|
+
return {
|
|
11
|
+
value,
|
|
12
|
+
toggle,
|
|
13
|
+
setValue,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
import { ThemeProvider } from "./theme-provider";
|
|
5
|
+
|
|
6
|
+
type ProvidersProps = {
|
|
7
|
+
children: ReactNode;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export function Providers({ children }: ProvidersProps) {
|
|
11
|
+
return <ThemeProvider>{children}</ThemeProvider>;
|
|
12
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
type ThemeProviderProps = {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export function ThemeProvider({ children }: ThemeProviderProps) {
|
|
10
|
+
return <div className="min-h-screen bg-white text-zinc-900">{children}</div>;
|
|
11
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { env } from "@/config/env";
|
|
2
|
+
import type { User } from "@/types/user";
|
|
3
|
+
|
|
4
|
+
export async function fetchHealth() {
|
|
5
|
+
const response = await fetch(`${env.apiUrl}/health`);
|
|
6
|
+
|
|
7
|
+
if (!response.ok) {
|
|
8
|
+
throw new Error("Health check failed");
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return response.json();
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export async function fetchCurrentUser(): Promise<User> {
|
|
15
|
+
const response = await fetch(`${env.apiUrl}/users/me`);
|
|
16
|
+
|
|
17
|
+
if (!response.ok) {
|
|
18
|
+
throw new Error("Failed to fetch user");
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
return response.json();
|
|
22
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement>;
|
|
2
|
+
|
|
3
|
+
export function Button({ children, ...props }: ButtonProps) {
|
|
4
|
+
return (
|
|
5
|
+
<button
|
|
6
|
+
{...props}
|
|
7
|
+
className="rounded-md bg-black px-4 py-2 text-white"
|
|
8
|
+
>
|
|
9
|
+
{children}
|
|
10
|
+
</button>
|
|
11
|
+
);
|
|
12
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./routes";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./useToggle";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./cn";
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@prmvx/frontend-forge",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A modern CLI to scaffold production-ready frontend architectures and starter modules for existing Next.js projects.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cli",
|
|
7
|
+
"nextjs",
|
|
8
|
+
"react",
|
|
9
|
+
"frontend",
|
|
10
|
+
"starter",
|
|
11
|
+
"boilerplate",
|
|
12
|
+
"scaffold",
|
|
13
|
+
"architecture",
|
|
14
|
+
"template",
|
|
15
|
+
"generator",
|
|
16
|
+
"typescript",
|
|
17
|
+
"developer-tools",
|
|
18
|
+
"productivity",
|
|
19
|
+
"app-router"
|
|
20
|
+
],
|
|
21
|
+
"homepage": "https://github.com/Parimal2607/frontend-forge#readme",
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/Parimal2607/frontend-forge.git"
|
|
25
|
+
},
|
|
26
|
+
"bugs": {
|
|
27
|
+
"url": "https://github.com/Parimal2607/frontend-forge/issues"
|
|
28
|
+
},
|
|
29
|
+
"author": {
|
|
30
|
+
"name": "Parimal Sharma",
|
|
31
|
+
"url": "https://github.com/Parimal2607"
|
|
32
|
+
},
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"type": "module",
|
|
35
|
+
"bin": {
|
|
36
|
+
"frontend-forge": "./dist/cli.js"
|
|
37
|
+
},
|
|
38
|
+
"files": [
|
|
39
|
+
"dist",
|
|
40
|
+
"README.md",
|
|
41
|
+
"LICENSE"
|
|
42
|
+
],
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=20"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"clean": "rimraf dist",
|
|
48
|
+
"build": "npm run clean && tsup && npm run copy-templates",
|
|
49
|
+
"copy-templates": "cpy \"templates/**/*\" dist/templates",
|
|
50
|
+
"dev": "tsup --watch",
|
|
51
|
+
"prepare": "npm run build"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@clack/prompts": "^1.7.0",
|
|
55
|
+
"commander": "^12.0.0",
|
|
56
|
+
"execa": "^9.6.1",
|
|
57
|
+
"fs-extra": "^11.2.0",
|
|
58
|
+
"picocolors": "^1.1.1"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@types/node": "^22.0.0",
|
|
62
|
+
"cpy-cli": "^7.0.0",
|
|
63
|
+
"rimraf": "^6.0.1",
|
|
64
|
+
"tsup": "^8.0.0",
|
|
65
|
+
"typescript": "^5.8.0"
|
|
66
|
+
},
|
|
67
|
+
"publishConfig": {
|
|
68
|
+
"access": "public"
|
|
69
|
+
}
|
|
70
|
+
}
|