create-react-forge 1.0.2 → 1.0.3
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 +88 -61
- package/dist/cli/index.js +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/parser.js +1 -1
- package/dist/cli/parser.js.map +1 -1
- package/dist/docs/architecture-generator.js +1 -1
- package/dist/generator/index.js +1 -1
- package/dist/generator/index.js.map +1 -1
- package/package.json +2 -1
- package/src/templates/overlays/base/manifest.json +16 -0
- package/src/templates/overlays/base/src/components/ui/Button.tsx +66 -0
- package/src/templates/overlays/base/src/components/ui/Input.tsx +51 -0
- package/src/templates/overlays/base/src/components/ui/index.ts +3 -0
- package/src/templates/overlays/base/src/hooks/use-disclosure.ts +21 -0
- package/src/templates/overlays/base/src/hooks/use-local-storage.ts +80 -0
- package/src/templates/overlays/base/src/lib/api-client.ts +101 -0
- package/src/templates/overlays/base/src/lib/utils.ts +34 -0
- package/src/templates/overlays/base/src/types/api.ts +47 -0
- package/src/templates/overlays/features/tanstack-query/manifest.json +17 -0
- package/src/templates/overlays/features/tanstack-query/src/features/users/api/create-user.ts +41 -0
- package/src/templates/overlays/features/tanstack-query/src/features/users/api/get-user.ts +27 -0
- package/src/templates/overlays/features/tanstack-query/src/features/users/api/get-users.ts +39 -0
- package/src/templates/overlays/features/tanstack-query/src/hooks/use-query-config.ts +42 -0
- package/src/templates/overlays/features/tanstack-query/src/lib/QueryProvider.tsx +28 -0
- package/src/templates/overlays/features/tanstack-query/src/lib/react-query.ts +46 -0
- package/src/templates/overlays/runtime/nextjs/manifest.json +27 -0
- package/src/templates/overlays/runtime/nextjs/next-env.d.ts +6 -0
- package/src/templates/overlays/runtime/nextjs/next.config.js +12 -0
- package/src/templates/overlays/runtime/nextjs/src/app/error.tsx +34 -0
- package/src/templates/overlays/runtime/nextjs/src/app/layout.tsx +23 -0
- package/src/templates/overlays/runtime/nextjs/src/app/loading.tsx +12 -0
- package/src/templates/overlays/runtime/nextjs/src/app/not-found.tsx +26 -0
- package/src/templates/overlays/runtime/nextjs/src/app/page.tsx +33 -0
- package/src/templates/overlays/runtime/nextjs/src/app/providers.tsx +14 -0
- package/src/templates/overlays/runtime/nextjs/src/styles/globals.css +50 -0
- package/src/templates/overlays/runtime/nextjs/tsconfig.json +29 -0
- package/src/templates/overlays/runtime/vite/index.html +14 -0
- package/src/templates/overlays/runtime/vite/manifest.json +28 -0
- package/src/templates/overlays/runtime/vite/public/vite.svg +2 -0
- package/src/templates/overlays/runtime/vite/src/app/App.tsx +11 -0
- package/src/templates/overlays/runtime/vite/src/app/provider.tsx +20 -0
- package/src/templates/overlays/runtime/vite/src/app/router.tsx +19 -0
- package/src/templates/overlays/runtime/vite/src/components/errors/ErrorFallback.tsx +21 -0
- package/src/templates/overlays/runtime/vite/src/components/ui/LoadingSpinner.tsx +23 -0
- package/src/templates/overlays/runtime/vite/src/features/misc/routes/Landing.tsx +33 -0
- package/src/templates/overlays/runtime/vite/src/features/misc/routes/NotFound.tsx +26 -0
- package/src/templates/overlays/runtime/vite/src/main.tsx +11 -0
- package/src/templates/overlays/runtime/vite/src/styles/globals.css +55 -0
- package/src/templates/overlays/runtime/vite/tsconfig.json +32 -0
- package/src/templates/overlays/runtime/vite/tsconfig.node.json +23 -0
- package/src/templates/overlays/runtime/vite/vite.config.ts +22 -0
- package/src/templates/overlays/state/redux/manifest.json +17 -0
- package/src/templates/overlays/state/redux/src/stores/Provider.tsx +17 -0
- package/src/templates/overlays/state/redux/src/stores/hooks.ts +11 -0
- package/src/templates/overlays/state/redux/src/stores/index.ts +17 -0
- package/src/templates/overlays/state/redux/src/stores/slices/auth.ts +54 -0
- package/src/templates/overlays/state/redux/src/stores/slices/notifications.ts +58 -0
- package/src/templates/overlays/state/redux/src/stores/store.ts +27 -0
- package/src/templates/overlays/state/zustand/manifest.json +16 -0
- package/src/templates/overlays/state/zustand/src/stores/auth.ts +48 -0
- package/src/templates/overlays/state/zustand/src/stores/index.ts +3 -0
- package/src/templates/overlays/state/zustand/src/stores/notifications.ts +54 -0
- package/src/templates/overlays/styling/css-modules/manifest.json +14 -0
- package/src/templates/overlays/styling/css-modules/src/components/ui/Button.module.css +87 -0
- package/src/templates/overlays/styling/css-modules/src/styles/globals.css +91 -0
- package/src/templates/overlays/styling/tailwind/manifest.json +18 -0
- package/src/templates/overlays/styling/tailwind/postcss.config.js +7 -0
- package/src/templates/overlays/styling/tailwind/src/styles/globals.css +54 -0
- package/src/templates/overlays/styling/tailwind/tailwind.config.js +62 -0
- package/src/templates/overlays/testing/jest/jest.config.js +24 -0
- package/src/templates/overlays/testing/jest/manifest.json +27 -0
- package/src/templates/overlays/testing/jest/src/components/ui/__tests__/Button.test.tsx +33 -0
- package/src/templates/overlays/testing/jest/src/testing/mocks/browser.ts +17 -0
- package/src/templates/overlays/testing/jest/src/testing/mocks/handlers.ts +42 -0
- package/src/templates/overlays/testing/jest/src/testing/mocks/server.ts +8 -0
- package/src/templates/overlays/testing/jest/src/testing/setup.ts +20 -0
- package/src/templates/overlays/testing/jest/src/testing/test-utils.tsx +39 -0
- package/src/templates/overlays/testing/playwright/manifest.json +21 -0
- package/src/templates/overlays/testing/playwright/playwright.config.ts +53 -0
- package/src/templates/overlays/testing/playwright/tests/e2e/accessibility.spec.ts +41 -0
- package/src/templates/overlays/testing/playwright/tests/e2e/home.spec.ts +41 -0
- package/src/templates/overlays/testing/vitest/manifest.json +28 -0
- package/src/templates/overlays/testing/vitest/src/components/ui/__tests__/Button.test.tsx +34 -0
- package/src/templates/overlays/testing/vitest/src/testing/mocks/browser.ts +17 -0
- package/src/templates/overlays/testing/vitest/src/testing/mocks/handlers.ts +42 -0
- package/src/templates/overlays/testing/vitest/src/testing/mocks/server.ts +8 -0
- package/src/templates/overlays/testing/vitest/src/testing/setup.ts +21 -0
- package/src/templates/overlays/testing/vitest/src/testing/test-utils.tsx +39 -0
- package/src/templates/overlays/testing/vitest/vitest.config.ts +31 -0
package/README.md
CHANGED
|
@@ -1,21 +1,17 @@
|
|
|
1
|
-
# react-
|
|
1
|
+
# create-react-forge
|
|
2
2
|
|
|
3
|
-
Production-ready React CLI
|
|
3
|
+
Production-ready React scaffolding CLI with first-class testing, flexible runtimes (Vite/Next.js), and a composable template system inspired by [bulletproof-react](https://github.com/alan2207/bulletproof-react).
|
|
4
4
|
|
|
5
|
-
##
|
|
5
|
+
## Requirements
|
|
6
6
|
|
|
7
|
-
-
|
|
8
|
-
- 🧪 **Testing as First-Class Citizen** — Vitest, Jest, React Testing Library, Playwright, Cypress
|
|
9
|
-
- 🎨 **Flexible Styling** — Tailwind CSS, CSS Modules, or plain CSS
|
|
10
|
-
- 📦 **State Management** — Zustand or Redux Toolkit
|
|
11
|
-
- 🔄 **Data Fetching** — TanStack Query with DevTools
|
|
12
|
-
- 📁 **Feature-Based Architecture** — Scalable project structure
|
|
13
|
-
- ⚡ **Zero Config** — Smart defaults, minimal prompts
|
|
7
|
+
- Node.js **>= 18**
|
|
14
8
|
|
|
15
|
-
## Quick
|
|
9
|
+
## Quick start
|
|
10
|
+
|
|
11
|
+
Create a new project (interactive):
|
|
16
12
|
|
|
17
13
|
```bash
|
|
18
|
-
npx create-react-forge
|
|
14
|
+
npx create-react-forge@latest
|
|
19
15
|
```
|
|
20
16
|
|
|
21
17
|
Or install globally:
|
|
@@ -25,9 +21,38 @@ npm install -g create-react-forge
|
|
|
25
21
|
create-react-forge
|
|
26
22
|
```
|
|
27
23
|
|
|
28
|
-
## What
|
|
24
|
+
## What it does
|
|
25
|
+
|
|
26
|
+
When you run `create-react-forge`, it will:
|
|
27
|
+
|
|
28
|
+
- Ask a few questions (runtime, language, styling, testing, etc.)
|
|
29
|
+
- Generate a new project directory (the directory **must not already exist**)
|
|
30
|
+
- Optionally initialize a git repo (depending on your answers)
|
|
31
|
+
- Print the “next steps” commands
|
|
32
|
+
|
|
33
|
+
Note: it **does not automatically install dependencies** — you’ll run your package manager install after generation.
|
|
34
|
+
|
|
35
|
+
## Interactive prompts (current)
|
|
36
|
+
|
|
37
|
+
The CLI is currently **prompt-driven**. You’ll choose:
|
|
38
|
+
|
|
39
|
+
- **Project name** (lowercase letters/numbers/hyphens)
|
|
40
|
+
- **Project directory**
|
|
41
|
+
- **Runtime**: Vite or Next.js
|
|
42
|
+
- **Language**: TypeScript or JavaScript
|
|
43
|
+
- **Styling**: Tailwind, CSS, Styled Components, or CSS Modules
|
|
44
|
+
- **State**: none, Zustand, or Redux Toolkit
|
|
45
|
+
- **Testing**: full (unit+component+E2E), unit+component only, or none
|
|
46
|
+
- **Unit runner**: Vitest or Jest (if testing enabled)
|
|
47
|
+
- **E2E runner**: Playwright or Cypress (if full testing)
|
|
48
|
+
- **Data fetching**: include TanStack Query
|
|
49
|
+
- **Package manager**: npm / yarn / pnpm
|
|
50
|
+
- **Git init**: yes/no
|
|
51
|
+
- **Prettier**: yes/no
|
|
29
52
|
|
|
30
|
-
|
|
53
|
+
## What you get
|
|
54
|
+
|
|
55
|
+
A production-ready React project with a scalable, feature-based structure:
|
|
31
56
|
|
|
32
57
|
```
|
|
33
58
|
my-app/
|
|
@@ -37,72 +62,74 @@ my-app/
|
|
|
37
62
|
│ ├── features/ # Feature-based modules
|
|
38
63
|
│ ├── hooks/ # Custom hooks
|
|
39
64
|
│ ├── lib/ # Utilities, API client
|
|
40
|
-
│ ├── stores/ # State management
|
|
41
|
-
│ ├── testing/ # Test utilities, mocks
|
|
42
|
-
│ └── types/ #
|
|
43
|
-
├── tests/ # E2E tests
|
|
65
|
+
│ ├── stores/ # State management (if selected)
|
|
66
|
+
│ ├── testing/ # Test utilities, mocks (if selected)
|
|
67
|
+
│ └── types/ # Shared types
|
|
68
|
+
├── tests/ # E2E tests (if selected)
|
|
44
69
|
└── [config files]
|
|
45
70
|
```
|
|
46
71
|
|
|
47
|
-
## Configuration
|
|
72
|
+
## Configuration options (summary)
|
|
48
73
|
|
|
49
|
-
|
|
|
50
|
-
|
|
51
|
-
| **Runtime** |
|
|
52
|
-
| **Language** |
|
|
53
|
-
| **Styling** |
|
|
54
|
-
| **State** |
|
|
55
|
-
| **
|
|
56
|
-
| **Unit
|
|
57
|
-
| **E2E
|
|
58
|
-
| **
|
|
74
|
+
| Category | Choices |
|
|
75
|
+
|---|---|
|
|
76
|
+
| **Runtime** | `vite`, `nextjs` |
|
|
77
|
+
| **Language** | `typescript`, `javascript` |
|
|
78
|
+
| **Styling** | `tailwind`, `css`, `styled-components`, `css-modules` |
|
|
79
|
+
| **State** | `none`, `zustand`, `redux` |
|
|
80
|
+
| **Testing** | `full`, `unit-component`, `none` |
|
|
81
|
+
| **Unit runner** | `vitest`, `jest` |
|
|
82
|
+
| **E2E runner** | `playwright`, `cypress` |
|
|
83
|
+
| **Data fetching** | TanStack Query on/off |
|
|
84
|
+
| **Package manager** | `npm`, `yarn`, `pnpm` |
|
|
85
|
+
| **Formatting** | Prettier on/off |
|
|
86
|
+
| **Git** | init on/off |
|
|
59
87
|
|
|
60
|
-
##
|
|
88
|
+
## Next steps (after generation)
|
|
61
89
|
|
|
62
|
-
|
|
90
|
+
```bash
|
|
91
|
+
cd <your-project>
|
|
92
|
+
npm install
|
|
93
|
+
npm run dev
|
|
94
|
+
```
|
|
63
95
|
|
|
64
|
-
|
|
65
|
-
- Co-located tests with features
|
|
66
|
-
- Centralized API client
|
|
67
|
-
- Type-safe throughout
|
|
96
|
+
## Advanced: config schema & templates API
|
|
68
97
|
|
|
69
|
-
|
|
98
|
+
This package exposes a couple of **advanced** entrypoints intended for tooling:
|
|
70
99
|
|
|
71
|
-
|
|
100
|
+
### Config schema (Zod)
|
|
72
101
|
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
npm install
|
|
102
|
+
```ts
|
|
103
|
+
import { ProjectConfigSchema, DEFAULT_CONFIG } from 'create-react-forge/config';
|
|
76
104
|
|
|
77
|
-
|
|
78
|
-
|
|
105
|
+
const parsed = ProjectConfigSchema.parse(DEFAULT_CONFIG);
|
|
106
|
+
```
|
|
79
107
|
|
|
80
|
-
|
|
81
|
-
npm run test
|
|
82
|
-
npm run test:watch
|
|
108
|
+
### Template registry
|
|
83
109
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
```
|
|
110
|
+
```ts
|
|
111
|
+
import { TemplateRegistry } from 'create-react-forge/templates';
|
|
87
112
|
|
|
88
|
-
|
|
113
|
+
const registry = new TemplateRegistry();
|
|
114
|
+
// registry.loadTemplatesForConfig(...) etc.
|
|
115
|
+
```
|
|
89
116
|
|
|
90
|
-
|
|
117
|
+
## Troubleshooting
|
|
91
118
|
|
|
92
|
-
|
|
119
|
+
- **“Directory already exists”**: pick a new project directory (or delete the existing folder).
|
|
120
|
+
- **Node version issues**: ensure `node -v` is **18+**.
|
|
121
|
+
- **Install step**: dependencies are not installed automatically — run your package manager install in the generated folder.
|
|
93
122
|
|
|
94
|
-
|
|
95
|
-
2. Create a feature branch: `git checkout -b feature/amazing-feature`
|
|
96
|
-
3. Make your changes
|
|
97
|
-
4. Run tests: `npm run test`
|
|
98
|
-
5. Submit a pull request
|
|
123
|
+
## Architecture & development
|
|
99
124
|
|
|
100
|
-
|
|
125
|
+
See [ARCHITECTURE.md](./ARCHITECTURE.md) for internal design details.
|
|
101
126
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
127
|
+
```bash
|
|
128
|
+
npm install
|
|
129
|
+
npm run dev
|
|
130
|
+
npm run test
|
|
131
|
+
npm run build
|
|
132
|
+
```
|
|
106
133
|
|
|
107
134
|
## License
|
|
108
135
|
|
package/dist/cli/index.js
CHANGED
|
@@ -70,7 +70,7 @@ function displayProjectSummary(config) {
|
|
|
70
70
|
* Main CLI entry point
|
|
71
71
|
*/
|
|
72
72
|
export async function main() {
|
|
73
|
-
console.log(chalk.cyan.bold('\n ⚛️ react-
|
|
73
|
+
console.log(chalk.cyan.bold('\n ⚛️ create-react-forge\n'));
|
|
74
74
|
console.log(chalk.gray(' Production-ready React scaffolder with first-class testing\n'));
|
|
75
75
|
try {
|
|
76
76
|
// Get user input
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/parser.js
CHANGED
|
@@ -18,7 +18,7 @@ function getVersion() {
|
|
|
18
18
|
export function createCommand() {
|
|
19
19
|
const program = new Command();
|
|
20
20
|
program
|
|
21
|
-
.name('react-
|
|
21
|
+
.name('create-react-forge')
|
|
22
22
|
.description('Production-ready React CLI scaffolder with first-class testing support')
|
|
23
23
|
.version(getVersion());
|
|
24
24
|
program
|
package/dist/cli/parser.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/cli/parser.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AAEtC,gCAAgC;AAChC,SAAS,UAAU;IACjB,IAAI,CAAC;QACH,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,oBAAoB,CAAC,CAAC;QAC9D,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;QACvE,OAAO,WAAW,CAAC,OAAO,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,OAAO,CAAC;IACjB,CAAC;AACH,CAAC;AAED,MAAM,UAAU,aAAa;IAC3B,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;IAE9B,OAAO;SACJ,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/cli/parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -4,7 +4,7 @@ export function generateArchitectureDoc(config) {
|
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
7
|
-
This project was bootstrapped with \`react-
|
|
7
|
+
This project was bootstrapped with \`create-react-forge\` using:
|
|
8
8
|
|
|
9
9
|
- **Runtime**: ${runtime === 'vite' ? 'Vite (SPA)' : 'Next.js (App Router)'}
|
|
10
10
|
- **Language**: ${language === 'typescript' ? 'TypeScript' : 'JavaScript'}
|
package/dist/generator/index.js
CHANGED
|
@@ -158,7 +158,7 @@ playwright-report/
|
|
|
158
158
|
cwd: this.config.path,
|
|
159
159
|
stdio: 'ignore',
|
|
160
160
|
});
|
|
161
|
-
execSync('git commit -m "Initial commit from react-
|
|
161
|
+
execSync('git commit -m "Initial commit from create-react-forge"', {
|
|
162
162
|
cwd: this.config.path,
|
|
163
163
|
stdio: 'ignore',
|
|
164
164
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/generator/index.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-react-forge",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "Production-ready React CLI scaffolder with Vite/Next.js, testing as first-class citizen",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -46,6 +46,7 @@
|
|
|
46
46
|
"license": "MIT",
|
|
47
47
|
"files": [
|
|
48
48
|
"dist",
|
|
49
|
+
"src/templates/overlays",
|
|
49
50
|
"README.md",
|
|
50
51
|
"LICENSE"
|
|
51
52
|
],
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "base",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Base shared utilities, types, and hooks following bulletproof-react patterns",
|
|
5
|
+
"compatibleWith": ["runtime-vite", "runtime-nextjs"],
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"clsx": "^2.1.0"
|
|
8
|
+
},
|
|
9
|
+
"devDependencies": {},
|
|
10
|
+
"scripts": {},
|
|
11
|
+
"filePatterns": {
|
|
12
|
+
"include": ["**/*"],
|
|
13
|
+
"exclude": ["manifest.json"]
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
|
|
4
|
+
export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
5
|
+
variant?: 'primary' | 'secondary' | 'outline' | 'ghost' | 'danger';
|
|
6
|
+
size?: 'sm' | 'md' | 'lg';
|
|
7
|
+
isLoading?: boolean;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
const variants = {
|
|
11
|
+
primary:
|
|
12
|
+
'bg-indigo-600 text-white hover:bg-indigo-500 focus-visible:outline-indigo-600',
|
|
13
|
+
secondary:
|
|
14
|
+
'bg-gray-100 text-gray-900 hover:bg-gray-200 focus-visible:outline-gray-600',
|
|
15
|
+
outline:
|
|
16
|
+
'border border-gray-300 bg-transparent text-gray-700 hover:bg-gray-50 focus-visible:outline-gray-600',
|
|
17
|
+
ghost:
|
|
18
|
+
'bg-transparent text-gray-700 hover:bg-gray-100 focus-visible:outline-gray-600',
|
|
19
|
+
danger:
|
|
20
|
+
'bg-red-600 text-white hover:bg-red-500 focus-visible:outline-red-600',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const sizes = {
|
|
24
|
+
sm: 'px-2.5 py-1.5 text-xs',
|
|
25
|
+
md: 'px-3.5 py-2.5 text-sm',
|
|
26
|
+
lg: 'px-4 py-3 text-base',
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export const Button = forwardRef<HTMLButtonElement, ButtonProps>(
|
|
30
|
+
(
|
|
31
|
+
{
|
|
32
|
+
className,
|
|
33
|
+
variant = 'primary',
|
|
34
|
+
size = 'md',
|
|
35
|
+
isLoading = false,
|
|
36
|
+
disabled,
|
|
37
|
+
children,
|
|
38
|
+
...props
|
|
39
|
+
},
|
|
40
|
+
ref
|
|
41
|
+
) => {
|
|
42
|
+
return (
|
|
43
|
+
<button
|
|
44
|
+
ref={ref}
|
|
45
|
+
className={cn(
|
|
46
|
+
'inline-flex items-center justify-center rounded-md font-semibold shadow-sm transition-colors',
|
|
47
|
+
'focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2',
|
|
48
|
+
'disabled:cursor-not-allowed disabled:opacity-50',
|
|
49
|
+
variants[variant],
|
|
50
|
+
sizes[size],
|
|
51
|
+
className
|
|
52
|
+
)}
|
|
53
|
+
disabled={disabled || isLoading}
|
|
54
|
+
{...props}
|
|
55
|
+
>
|
|
56
|
+
{isLoading && (
|
|
57
|
+
<span className="mr-2 h-4 w-4 animate-spin rounded-full border-2 border-current border-t-transparent" />
|
|
58
|
+
)}
|
|
59
|
+
{children}
|
|
60
|
+
</button>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
Button.displayName = 'Button';
|
|
66
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { forwardRef } from 'react';
|
|
2
|
+
import { cn } from '@/lib/utils';
|
|
3
|
+
|
|
4
|
+
export type InputProps = React.InputHTMLAttributes<HTMLInputElement> & {
|
|
5
|
+
label?: string;
|
|
6
|
+
error?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const Input = forwardRef<HTMLInputElement, InputProps>(
|
|
10
|
+
({ className, label, error, id, ...props }, ref) => {
|
|
11
|
+
const inputId = id || props.name;
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
<div className="w-full">
|
|
15
|
+
{label && (
|
|
16
|
+
<label
|
|
17
|
+
htmlFor={inputId}
|
|
18
|
+
className="mb-1 block text-sm font-medium text-gray-700"
|
|
19
|
+
>
|
|
20
|
+
{label}
|
|
21
|
+
</label>
|
|
22
|
+
)}
|
|
23
|
+
<input
|
|
24
|
+
ref={ref}
|
|
25
|
+
id={inputId}
|
|
26
|
+
className={cn(
|
|
27
|
+
'block w-full rounded-md border-0 px-3 py-2 text-gray-900 shadow-sm ring-1 ring-inset',
|
|
28
|
+
'placeholder:text-gray-400',
|
|
29
|
+
'focus:ring-2 focus:ring-inset focus:ring-indigo-600',
|
|
30
|
+
'disabled:cursor-not-allowed disabled:bg-gray-50 disabled:text-gray-500',
|
|
31
|
+
error
|
|
32
|
+
? 'ring-red-300 focus:ring-red-500'
|
|
33
|
+
: 'ring-gray-300',
|
|
34
|
+
className
|
|
35
|
+
)}
|
|
36
|
+
aria-invalid={error ? 'true' : 'false'}
|
|
37
|
+
aria-describedby={error ? `${inputId}-error` : undefined}
|
|
38
|
+
{...props}
|
|
39
|
+
/>
|
|
40
|
+
{error && (
|
|
41
|
+
<p id={`${inputId}-error`} className="mt-1 text-sm text-red-600">
|
|
42
|
+
{error}
|
|
43
|
+
</p>
|
|
44
|
+
)}
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
}
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
Input.displayName = 'Input';
|
|
51
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { useCallback, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hook for managing disclosure state (modals, dropdowns, etc.)
|
|
5
|
+
* Following bulletproof-react patterns
|
|
6
|
+
*/
|
|
7
|
+
export function useDisclosure(initialState = false) {
|
|
8
|
+
const [isOpen, setIsOpen] = useState(initialState);
|
|
9
|
+
|
|
10
|
+
const open = useCallback(() => setIsOpen(true), []);
|
|
11
|
+
const close = useCallback(() => setIsOpen(false), []);
|
|
12
|
+
const toggle = useCallback(() => setIsOpen((prev) => !prev), []);
|
|
13
|
+
|
|
14
|
+
return {
|
|
15
|
+
isOpen,
|
|
16
|
+
open,
|
|
17
|
+
close,
|
|
18
|
+
toggle,
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { useCallback, useEffect, useState } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hook for syncing state with localStorage
|
|
5
|
+
*/
|
|
6
|
+
export function useLocalStorage<T>(
|
|
7
|
+
key: string,
|
|
8
|
+
initialValue: T
|
|
9
|
+
): [T, (value: T | ((prev: T) => T)) => void, () => void] {
|
|
10
|
+
// Get stored value or use initial value
|
|
11
|
+
const readValue = useCallback((): T => {
|
|
12
|
+
if (typeof window === 'undefined') {
|
|
13
|
+
return initialValue;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const item = window.localStorage.getItem(key);
|
|
18
|
+
return item ? (JSON.parse(item) as T) : initialValue;
|
|
19
|
+
} catch (error) {
|
|
20
|
+
console.warn(`Error reading localStorage key "${key}":`, error);
|
|
21
|
+
return initialValue;
|
|
22
|
+
}
|
|
23
|
+
}, [initialValue, key]);
|
|
24
|
+
|
|
25
|
+
const [storedValue, setStoredValue] = useState<T>(readValue);
|
|
26
|
+
|
|
27
|
+
// Set value to localStorage
|
|
28
|
+
const setValue = useCallback(
|
|
29
|
+
(value: T | ((prev: T) => T)) => {
|
|
30
|
+
if (typeof window === 'undefined') {
|
|
31
|
+
console.warn(`Cannot set localStorage key "${key}" during SSR`);
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const valueToStore = value instanceof Function ? value(storedValue) : value;
|
|
37
|
+
window.localStorage.setItem(key, JSON.stringify(valueToStore));
|
|
38
|
+
setStoredValue(valueToStore);
|
|
39
|
+
|
|
40
|
+
// Dispatch storage event for other tabs/windows
|
|
41
|
+
window.dispatchEvent(new Event('local-storage'));
|
|
42
|
+
} catch (error) {
|
|
43
|
+
console.warn(`Error setting localStorage key "${key}":`, error);
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
[key, storedValue]
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
// Remove value from localStorage
|
|
50
|
+
const removeValue = useCallback(() => {
|
|
51
|
+
if (typeof window === 'undefined') {
|
|
52
|
+
return;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
try {
|
|
56
|
+
window.localStorage.removeItem(key);
|
|
57
|
+
setStoredValue(initialValue);
|
|
58
|
+
} catch (error) {
|
|
59
|
+
console.warn(`Error removing localStorage key "${key}":`, error);
|
|
60
|
+
}
|
|
61
|
+
}, [initialValue, key]);
|
|
62
|
+
|
|
63
|
+
// Listen for changes in other tabs/windows
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
const handleStorageChange = () => {
|
|
66
|
+
setStoredValue(readValue());
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
window.addEventListener('storage', handleStorageChange);
|
|
70
|
+
window.addEventListener('local-storage', handleStorageChange);
|
|
71
|
+
|
|
72
|
+
return () => {
|
|
73
|
+
window.removeEventListener('storage', handleStorageChange);
|
|
74
|
+
window.removeEventListener('local-storage', handleStorageChange);
|
|
75
|
+
};
|
|
76
|
+
}, [readValue]);
|
|
77
|
+
|
|
78
|
+
return [storedValue, setValue, removeValue];
|
|
79
|
+
}
|
|
80
|
+
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API Client - Centralized HTTP client following bulletproof-react patterns
|
|
3
|
+
* Replace with your actual API configuration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type RequestConfig = {
|
|
7
|
+
method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
body?: unknown;
|
|
10
|
+
params?: Record<string, string | number | boolean>;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export type ApiResponse<T> = {
|
|
14
|
+
data: T;
|
|
15
|
+
status: number;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const API_URL = import.meta.env.VITE_API_URL || 'http://localhost:3001';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Build URL with query parameters
|
|
22
|
+
*/
|
|
23
|
+
function buildUrl(endpoint: string, params?: Record<string, string | number | boolean>): string {
|
|
24
|
+
const url = new URL(endpoint, API_URL);
|
|
25
|
+
|
|
26
|
+
if (params) {
|
|
27
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
28
|
+
url.searchParams.append(key, String(value));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return url.toString();
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Get authorization headers (customize based on your auth strategy)
|
|
37
|
+
*/
|
|
38
|
+
function getAuthHeaders(): Record<string, string> {
|
|
39
|
+
const token = localStorage.getItem('token');
|
|
40
|
+
|
|
41
|
+
if (token) {
|
|
42
|
+
return { Authorization: `Bearer ${token}` };
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return {};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Main API client function
|
|
50
|
+
*/
|
|
51
|
+
export async function apiClient<T>(
|
|
52
|
+
endpoint: string,
|
|
53
|
+
config: RequestConfig = {}
|
|
54
|
+
): Promise<ApiResponse<T>> {
|
|
55
|
+
const { method = 'GET', headers = {}, body, params } = config;
|
|
56
|
+
|
|
57
|
+
const url = buildUrl(endpoint, params);
|
|
58
|
+
|
|
59
|
+
const response = await fetch(url, {
|
|
60
|
+
method,
|
|
61
|
+
headers: {
|
|
62
|
+
'Content-Type': 'application/json',
|
|
63
|
+
...getAuthHeaders(),
|
|
64
|
+
...headers,
|
|
65
|
+
},
|
|
66
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
if (!response.ok) {
|
|
70
|
+
const error = await response.json().catch(() => ({}));
|
|
71
|
+
throw new Error(error.message || `HTTP error! status: ${response.status}`);
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const data = await response.json();
|
|
75
|
+
|
|
76
|
+
return {
|
|
77
|
+
data,
|
|
78
|
+
status: response.status,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Convenience methods
|
|
84
|
+
*/
|
|
85
|
+
export const api = {
|
|
86
|
+
get: <T>(endpoint: string, params?: Record<string, string | number | boolean>) =>
|
|
87
|
+
apiClient<T>(endpoint, { method: 'GET', params }),
|
|
88
|
+
|
|
89
|
+
post: <T>(endpoint: string, body: unknown) =>
|
|
90
|
+
apiClient<T>(endpoint, { method: 'POST', body }),
|
|
91
|
+
|
|
92
|
+
put: <T>(endpoint: string, body: unknown) =>
|
|
93
|
+
apiClient<T>(endpoint, { method: 'PUT', body }),
|
|
94
|
+
|
|
95
|
+
patch: <T>(endpoint: string, body: unknown) =>
|
|
96
|
+
apiClient<T>(endpoint, { method: 'PATCH', body }),
|
|
97
|
+
|
|
98
|
+
delete: <T>(endpoint: string) =>
|
|
99
|
+
apiClient<T>(endpoint, { method: 'DELETE' }),
|
|
100
|
+
};
|
|
101
|
+
|