create-react-scaffold-cli 1.0.2 → 1.0.5
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/package.json +1 -1
- package/templates/base/{readme.md → README.md} +165 -95
- package/templates/base/docs/DOCS.md +7 -0
- package/templates/base/index.html +3 -3
- package/templates/base/package.json +2 -0
- package/templates/base/public/icons/react.svg +1 -0
- package/templates/base/src/app/App.jsx +8 -6
- package/templates/base/src/app/Router.jsx +42 -2
- package/templates/base/src/app/index.css +36 -0
- package/templates/base/src/app/main.jsx +1 -1
- package/templates/base/src/app/middlewares/AuthMiddleware.jsx +5 -0
- package/templates/base/src/app/middlewares/index.js +1 -0
- package/templates/base/src/app/providers/QueryProvider.jsx +1 -1
- package/templates/base/src/app/routes.registry.js +8 -0
- package/templates/base/src/features/sample/constants/index.js +3 -0
- package/templates/base/src/features/sample/constants/sample.assets.js +8 -0
- package/templates/base/src/features/sample/constants/sample.navigations.js +5 -0
- package/templates/base/src/features/sample/constants/sample.queryKeys.js +3 -0
- package/templates/base/src/features/sample/index.js +1 -0
- package/templates/base/src/features/sample/pages/SamplePage.jsx +8 -0
- package/templates/base/src/features/sample/pages/index.js +3 -0
- package/templates/base/src/features/sample/sample.routes.js +12 -0
- package/templates/base/src/features/welcome/components/CodeLine.jsx +54 -0
- package/templates/base/src/features/welcome/components/Divider.jsx +7 -0
- package/templates/base/src/features/welcome/components/Footer.jsx +78 -0
- package/templates/base/src/features/welcome/components/Hero.jsx +131 -0
- package/templates/base/src/features/welcome/components/IconLink.jsx +18 -0
- package/templates/base/src/features/welcome/components/QuickStartPanel.jsx +63 -0
- package/templates/base/src/features/welcome/components/RingSoft.jsx +16 -0
- package/templates/base/src/features/welcome/components/StorySections.jsx +63 -0
- package/templates/base/src/features/welcome/components/WhatYouGet.jsx +49 -0
- package/templates/base/src/features/welcome/components/index.js +5 -0
- package/templates/base/src/features/welcome/constants/index.js +2 -0
- package/templates/base/src/features/welcome/constants/welcome.constants.js +21 -0
- package/templates/base/src/features/welcome/constants/welcome.navigations.js +3 -0
- package/templates/base/src/features/welcome/index.js +1 -0
- package/templates/base/src/features/welcome/pages/WelcomePage.jsx +28 -0
- package/templates/base/src/features/welcome/pages/index.js +3 -0
- package/templates/base/src/features/welcome/welcome.routes.js +12 -0
- package/templates/base/src/shared/{shared_readme.md → SHARED.md} +7 -1
- package/templates/base/src/shared/constants/app.constants.js +6 -0
- package/templates/base/src/shared/constants/assets.constants.js +5 -0
- package/templates/base/src/shared/constants/index.js +2 -0
- package/templates/base/src/shared/theme/theme.js +26 -15
- package/templates/base/src/shared/ui/Box.jsx +1 -14
- package/templates/base/src/shared/ui/Button.jsx +4 -5
- package/templates/base/src/shared/ui/DropdownMenu.jsx +57 -91
- package/templates/base/src/shared/ui/GridItem.jsx +1 -0
- package/templates/base/src/shared/ui/Modal.jsx +1 -0
- package/templates/base/src/shared/ui/Text.jsx +3 -3
- package/templates/base/src/shared/ui/index.js +17 -0
- package/templates/base/src/shared/utils/localStorage.js +18 -0
- package/templates/base/src/shared/utils/memo.js +6 -0
- package/templates/base/src/shared/utils/regix.js +3 -0
- package/templates/base/vercel.json +3 -0
- package/templates/base/vite.config.js +4 -5
- package/templates/base/src/features/sample/sample.assets.js +0 -0
- package/templates/base/src/features/sample/sample.navigations.js +0 -0
- package/templates/base/src/features/sample/sample.queryKeys.js +0 -0
- package/templates/base/src/features/sample/sample.routes.jsx +0 -0
- /package/templates/base/src/app/{app_readme.md → APP.md} +0 -0
- /package/templates/base/src/features/{features_readme.md → FEATURES.md} +0 -0
- /package/templates/base/src/{features/index.js → shared/utils/motion.js} +0 -0
package/package.json
CHANGED
|
@@ -1,95 +1,165 @@
|
|
|
1
|
-
# React Feature‑First Scaffold
|
|
2
|
-
|
|
3
|
-
## Purpose
|
|
4
|
-
|
|
5
|
-
This repository is an **
|
|
6
|
-
|
|
7
|
-
This scaffold will later be distributed via an internal **NPM CLI** (similar to `create-react-app`) to bootstrap projects with best practices preconfigured.
|
|
8
|
-
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
## Core Principles
|
|
12
|
-
|
|
13
|
-
- **Feature-first, not layer-first**
|
|
14
|
-
- **Explicit boundaries** between app / features / shared
|
|
15
|
-
- **Locality of logic** (keep things close to where they are used)
|
|
16
|
-
- **Predictable imports** and naming conventions
|
|
17
|
-
- **Low cognitive load** for new developers
|
|
18
|
-
|
|
19
|
-
---
|
|
20
|
-
|
|
21
|
-
## Tech Stack
|
|
22
|
-
|
|
23
|
-
### Runtime
|
|
24
|
-
|
|
25
|
-
- **React 19** – UI layer
|
|
26
|
-
- **Vite** – fast dev & build tooling
|
|
27
|
-
|
|
28
|
-
### Styling
|
|
29
|
-
|
|
30
|
-
- **Tailwind CSS** – utility-first styling
|
|
31
|
-
- **tailwind-merge** – class conflict resolution
|
|
32
|
-
- **clsx** – conditional class composition
|
|
33
|
-
|
|
34
|
-
### Data & State
|
|
35
|
-
|
|
36
|
-
- **@tanstack/react-query** – server-state management
|
|
37
|
-
- **Axios** – HTTP client
|
|
38
|
-
|
|
39
|
-
### UI Utilities
|
|
40
|
-
|
|
41
|
-
- **Radix UI** – accessible headless components
|
|
42
|
-
- **react-hot-toast** – notifications
|
|
43
|
-
- **react-icons** – icon system
|
|
44
|
-
|
|
45
|
-
### Code Quality
|
|
46
|
-
|
|
47
|
-
- **ESLint** – linting with strict rules
|
|
48
|
-
- **Prettier** – formatting
|
|
49
|
-
- **Husky + lint-staged** – pre-commit enforcement
|
|
50
|
-
|
|
51
|
-
---
|
|
52
|
-
|
|
53
|
-
## High-Level Folder Structure
|
|
54
|
-
|
|
55
|
-
```txt
|
|
56
|
-
src/
|
|
57
|
-
app/ # Application bootstrap & global wiring
|
|
58
|
-
features/ # Business features (isolated, self-contained)
|
|
59
|
-
shared/ # Cross-feature reusable modules
|
|
60
|
-
```
|
|
61
|
-
|
|
62
|
-
Each top-level folder has **its own README** explaining rules and responsibilities.
|
|
63
|
-
|
|
64
|
-
---
|
|
65
|
-
|
|
66
|
-
## Installation
|
|
67
|
-
|
|
68
|
-
> CLI installation instructions.
|
|
69
|
-
|
|
70
|
-
```bash
|
|
71
|
-
npx create-react-scaffold-cli
|
|
72
|
-
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
---
|
|
76
|
-
|
|
77
|
-
## Documentation Index
|
|
78
|
-
|
|
79
|
-
- `src/app/README.md` – Application bootstrap & providers
|
|
80
|
-
- `src/features/README.md` – Feature architecture rules
|
|
81
|
-
- `src/shared/README.md` – Shared modules & reuse policy
|
|
82
|
-
|
|
83
|
-
---
|
|
84
|
-
|
|
85
|
-
##
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
1
|
+
# React Feature‑First Scaffold
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
|
|
5
|
+
This repository is an **opinionated React scaffold** designed for large-scale frontend applications. It enforces a **feature‑first architecture**, clear ownership boundaries, and predictable patterns so teams can scale safely without architectural drift.
|
|
6
|
+
|
|
7
|
+
This scaffold will later be distributed via an internal **NPM CLI** (similar to `create-react-app`) to bootstrap projects with best practices preconfigured.
|
|
8
|
+
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
## Core Principles
|
|
12
|
+
|
|
13
|
+
- **Feature-first, not layer-first**
|
|
14
|
+
- **Explicit boundaries** between app / features / shared
|
|
15
|
+
- **Locality of logic** (keep things close to where they are used)
|
|
16
|
+
- **Predictable imports** and naming conventions
|
|
17
|
+
- **Low cognitive load** for new developers
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## Tech Stack
|
|
22
|
+
|
|
23
|
+
### Runtime
|
|
24
|
+
|
|
25
|
+
- **React 19** – UI layer
|
|
26
|
+
- **Vite** – fast dev & build tooling
|
|
27
|
+
|
|
28
|
+
### Styling
|
|
29
|
+
|
|
30
|
+
- **Tailwind CSS** – utility-first styling
|
|
31
|
+
- **tailwind-merge** – class conflict resolution
|
|
32
|
+
- **clsx** – conditional class composition
|
|
33
|
+
|
|
34
|
+
### Data & State
|
|
35
|
+
|
|
36
|
+
- **@tanstack/react-query** – server-state management
|
|
37
|
+
- **Axios** – HTTP client
|
|
38
|
+
|
|
39
|
+
### UI Utilities
|
|
40
|
+
|
|
41
|
+
- **Radix UI** – accessible headless components
|
|
42
|
+
- **react-hot-toast** – notifications
|
|
43
|
+
- **react-icons** – icon system
|
|
44
|
+
|
|
45
|
+
### Code Quality
|
|
46
|
+
|
|
47
|
+
- **ESLint** – linting with strict rules
|
|
48
|
+
- **Prettier** – formatting
|
|
49
|
+
- **Husky + lint-staged** – pre-commit enforcement
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## High-Level Folder Structure
|
|
54
|
+
|
|
55
|
+
```txt
|
|
56
|
+
src/
|
|
57
|
+
app/ # Application bootstrap & global wiring
|
|
58
|
+
features/ # Business features (isolated, self-contained)
|
|
59
|
+
shared/ # Cross-feature reusable modules
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Each top-level folder has **its own README** explaining rules and responsibilities.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
## Installation
|
|
67
|
+
|
|
68
|
+
> CLI installation instructions.
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npx create-react-scaffold-cli
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Documentation Index
|
|
78
|
+
|
|
79
|
+
- `src/app/README.md` – Application bootstrap & providers
|
|
80
|
+
- `src/features/README.md` – Feature architecture rules
|
|
81
|
+
- `src/shared/README.md` – Shared modules & reuse policy
|
|
82
|
+
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
## Set Up
|
|
86
|
+
|
|
87
|
+
### Install dependencies
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
npm i
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### Run application
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
npm run dev
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
|
102
|
+
|
|
103
|
+
### Lint application
|
|
104
|
+
|
|
105
|
+
```
|
|
106
|
+
npm run lint
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Prettify code
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
npm run prettier
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Build application
|
|
116
|
+
|
|
117
|
+
```
|
|
118
|
+
npm run build
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### Preview application
|
|
122
|
+
|
|
123
|
+
```
|
|
124
|
+
npm run preview
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
|
|
128
|
+
|
|
129
|
+
# Learning Resources
|
|
130
|
+
|
|
131
|
+
## Tailwind CSS
|
|
132
|
+
|
|
133
|
+
To learn more about `Tailwind CSS`, take a look at the following resources:
|
|
134
|
+
|
|
135
|
+
- [Tailwind ](https://tailwindcss.com) - Tailwind documentation and related resources.
|
|
136
|
+
|
|
137
|
+
## Framer Motion
|
|
138
|
+
|
|
139
|
+
To learn more about `Framer Motion`, take a look at the following resources:
|
|
140
|
+
|
|
141
|
+
- [Framer Motion](https://www.framer.com/motion) - Framer Motion documentation and related resources.
|
|
142
|
+
|
|
143
|
+
## React Query
|
|
144
|
+
|
|
145
|
+
To learn more about `TanStack Query`, take a look at the following resources:
|
|
146
|
+
|
|
147
|
+
- [TanStack Query](https://tanstack.com/query/latest) - React Query documentation and related resources.
|
|
148
|
+
|
|
149
|
+
## Nuqs
|
|
150
|
+
|
|
151
|
+
To learn more about `Nuqs`, take a look at the following resources:
|
|
152
|
+
|
|
153
|
+
- [Nuqs](https://nuqs.dev/) - React Query documentation and related resources.
|
|
154
|
+
|
|
155
|
+
## Philosophy
|
|
156
|
+
|
|
157
|
+
> **Architecture is a product feature.**
|
|
158
|
+
|
|
159
|
+
This scaffold exists to reduce decision fatigue, prevent architectural erosion, and help teams move faster with confidence.
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## Ownership
|
|
164
|
+
|
|
165
|
+
This scaffold is maintained internally and should be treated as a **living standard**. Changes must be intentional, documented, and agreed upon by the frontend team.
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8" />
|
|
5
|
-
<link rel="icon" type="image/svg+xml" href="/
|
|
5
|
+
<link rel="icon" type="image/svg+xml" href="/public/icons/react.svg" />
|
|
6
6
|
<meta
|
|
7
7
|
name="viewport"
|
|
8
8
|
content="width=device-width, initial-scale=1, viewport-fit=cover, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
|
9
9
|
/>
|
|
10
|
-
<title>
|
|
10
|
+
<title>React Scaffold App</title>
|
|
11
11
|
</head>
|
|
12
12
|
<body>
|
|
13
13
|
<div id="root"></div>
|
|
14
|
-
<script type="module" src="/src/main.jsx"></script>
|
|
14
|
+
<script type="module" src="/src/app/main.jsx"></script>
|
|
15
15
|
</body>
|
|
16
16
|
</html>
|
|
@@ -32,12 +32,14 @@
|
|
|
32
32
|
"@tanstack/react-query-devtools": "^5.91.2",
|
|
33
33
|
"axios": "^1.13.2",
|
|
34
34
|
"clsx": "^2.1.1",
|
|
35
|
+
"framer-motion": "^12.26.2",
|
|
35
36
|
"nuqs": "^2.8.6",
|
|
36
37
|
"postcss": "^8.5.6",
|
|
37
38
|
"react": "^19.2.0",
|
|
38
39
|
"react-dom": "^19.2.0",
|
|
39
40
|
"react-hot-toast": "^2.6.0",
|
|
40
41
|
"react-icons": "^5.5.0",
|
|
42
|
+
"react-router-dom": "^7.12.0",
|
|
41
43
|
"tailwind-merge": "^3.4.0",
|
|
42
44
|
"tailwindcss": "^4.1.18"
|
|
43
45
|
},
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="64" height="64" viewBox="0 0 32 32"><g transform="matrix(.05696 0 0 .05696 .647744 2.43826)" fill="none" fill-rule="evenodd"><circle r="50.167" cy="237.628" cx="269.529" fill="#00d8ff"/><g stroke="#00d8ff" stroke-width="24"><path d="M269.53 135.628c67.356 0 129.928 9.665 177.107 25.907 56.844 19.57 91.794 49.233 91.794 76.093 0 27.99-37.04 59.503-98.083 79.728-46.15 15.29-106.88 23.272-170.818 23.272-65.554 0-127.63-7.492-174.3-23.44-59.046-20.182-94.61-52.103-94.61-79.56 0-26.642 33.37-56.076 89.415-75.616 47.355-16.51 111.472-26.384 179.486-26.384z"/><path d="M180.736 186.922c33.65-58.348 73.28-107.724 110.92-140.48C337.006 6.976 380.163-8.48 403.43 4.937c24.248 13.983 33.042 61.814 20.067 124.796-9.8 47.618-33.234 104.212-65.176 159.6-32.75 56.788-70.25 106.82-107.377 139.272-46.98 41.068-92.4 55.93-116.185 42.213-23.08-13.3-31.906-56.92-20.834-115.233 9.355-49.27 32.832-109.745 66.8-168.664z"/><path d="M180.82 289.482C147.075 231.2 124.1 172.195 114.51 123.227c-11.544-59-3.382-104.11 19.864-117.566 24.224-14.024 70.055 2.244 118.14 44.94 36.356 32.28 73.688 80.837 105.723 136.173 32.844 56.733 57.46 114.21 67.036 162.582 12.117 61.213 2.31 107.984-21.453 121.74-23.057 13.348-65.25-.784-110.24-39.5-38.013-32.71-78.682-83.253-112.76-142.115z"/></g></g></svg>
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { Toaster } from '@/shared/ui';
|
|
1
|
+
import { Scrollable, Toaster } from '@/shared/ui';
|
|
2
2
|
import { QueryProvider } from './providers';
|
|
3
|
+
import { Router } from './Router';
|
|
4
|
+
import { memo } from '@/shared/utils';
|
|
3
5
|
|
|
4
|
-
|
|
6
|
+
export const App = memo(() => {
|
|
5
7
|
return (
|
|
6
8
|
<QueryProvider>
|
|
7
|
-
|
|
9
|
+
<Scrollable>
|
|
10
|
+
<Router />
|
|
11
|
+
</Scrollable>
|
|
8
12
|
<Toaster />
|
|
9
13
|
</QueryProvider>
|
|
10
14
|
);
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
export default App;
|
|
15
|
+
});
|
|
@@ -1,4 +1,44 @@
|
|
|
1
|
+
import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom';
|
|
2
|
+
import { featureRoutes } from './routes.registry';
|
|
3
|
+
import { AuthMiddleware } from './middlewares';
|
|
4
|
+
import { Layouts } from '@/shared/constants';
|
|
5
|
+
import { memo } from '@/shared/utils';
|
|
6
|
+
import React from 'react';
|
|
1
7
|
|
|
2
|
-
|
|
3
|
-
|
|
8
|
+
const layoutMap = {
|
|
9
|
+
dashboard: null,
|
|
10
|
+
none: ({ children }) => children,
|
|
4
11
|
};
|
|
12
|
+
|
|
13
|
+
export const Router = memo(() => {
|
|
14
|
+
return (
|
|
15
|
+
<BrowserRouter>
|
|
16
|
+
<Routes>
|
|
17
|
+
{featureRoutes.map((route, index) => {
|
|
18
|
+
const Layout = layoutMap[route.layout ?? Layouts.None];
|
|
19
|
+
const Page = route.element;
|
|
20
|
+
|
|
21
|
+
let element = (
|
|
22
|
+
<Layout>
|
|
23
|
+
<Page />
|
|
24
|
+
</Layout>
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
if (route.protected) {
|
|
28
|
+
element = (
|
|
29
|
+
<AuthMiddleware>
|
|
30
|
+
<Layout>
|
|
31
|
+
<Page />
|
|
32
|
+
</Layout>
|
|
33
|
+
</AuthMiddleware>
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
return <Route key={index} path={route.path} element={element} />;
|
|
38
|
+
})}
|
|
39
|
+
|
|
40
|
+
<Route path="/*" element={<Navigate to="/welcome" replace />} />
|
|
41
|
+
</Routes>
|
|
42
|
+
</BrowserRouter>
|
|
43
|
+
);
|
|
44
|
+
});
|
|
@@ -1 +1,37 @@
|
|
|
1
1
|
@import 'tailwindcss';
|
|
2
|
+
@import url('https://fonts.googleapis.com/css2?family=Plus+Jakarta+Sans:ital,wght@0,200..800;1,200..800&display=swap');
|
|
3
|
+
@import url('https://fonts.googleapis.com/css2?family=Inter:ital,opsz,wght@0,14..32,100..900;1,14..32,100..900&display=swap');
|
|
4
|
+
|
|
5
|
+
@theme {
|
|
6
|
+
/* Colors */
|
|
7
|
+
--color-primary: #3452ff;
|
|
8
|
+
--color-primary-foreground: #ffffff;
|
|
9
|
+
--color-badge: #fef1a7;
|
|
10
|
+
|
|
11
|
+
--color-bg: #ffffff;
|
|
12
|
+
--color-surface: #f7f7f7;
|
|
13
|
+
|
|
14
|
+
--color-ink: #03003e;
|
|
15
|
+
--color-muted: #797979;
|
|
16
|
+
|
|
17
|
+
--color-ring: color-mix(in oklab, var(--color-primary) 35%, transparent);
|
|
18
|
+
--color-border: color-mix(in oklab, var(--color-ink) 10%, transparent);
|
|
19
|
+
--color-soft: color-mix(in oklab, var(--color-primary) 10%, transparent);
|
|
20
|
+
|
|
21
|
+
/* Fonts */
|
|
22
|
+
--font-plus-jakarta-sans:
|
|
23
|
+
'Plus Jakarta Sans', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
|
|
24
|
+
--font-inter: 'Inter', ui-sans-serif, system-ui, -apple-system, 'Segoe UI', Arial, sans-serif;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
:root {
|
|
28
|
+
color: var(--color-ink);
|
|
29
|
+
background: var(--color-bg);
|
|
30
|
+
text-rendering: optimizeLegibility;
|
|
31
|
+
-webkit-font-smoothing: antialiased;
|
|
32
|
+
-moz-osx-font-smoothing: grayscale;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
body {
|
|
36
|
+
font-family: var(--font-inter);
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { AuthMiddleware } from './AuthMiddleware';
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
|
-
import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
3
2
|
import { AxiosError } from 'axios';
|
|
4
3
|
import toast from 'react-hot-toast';
|
|
5
4
|
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
|
|
5
|
+
import { MutationCache, QueryCache, QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
6
6
|
|
|
7
7
|
export const QueryProvider = ({ children }) => {
|
|
8
8
|
const [queryCache] = React.useState(
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { sampleRoutes } from './sample.routes';
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Layouts } from '@/shared/constants';
|
|
2
|
+
import { SamplePage } from './pages';
|
|
3
|
+
import { SampleNavigation } from './constants';
|
|
4
|
+
|
|
5
|
+
export const sampleRoutes = [
|
|
6
|
+
{
|
|
7
|
+
path: SampleNavigation.Sample,
|
|
8
|
+
element: SamplePage,
|
|
9
|
+
protected: true,
|
|
10
|
+
layout: Layouts.None,
|
|
11
|
+
},
|
|
12
|
+
];
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PiCopySimpleBold, PiCheckBold } from 'react-icons/pi';
|
|
3
|
+
import { Flex } from '@/shared/ui/Flex';
|
|
4
|
+
import { Text } from '@/shared/ui/Text';
|
|
5
|
+
import { useToggleState } from '@/shared/hooks';
|
|
6
|
+
import { Box, FlexItem } from '@/shared/ui';
|
|
7
|
+
import { cn } from '@/shared/libs';
|
|
8
|
+
|
|
9
|
+
export const CodeLine = React.memo(({ value, isStorySection }) => {
|
|
10
|
+
const [copied, toggleCopied] = useToggleState();
|
|
11
|
+
|
|
12
|
+
const onCopy = React.useCallback(async () => {
|
|
13
|
+
try {
|
|
14
|
+
await navigator.clipboard.writeText(value);
|
|
15
|
+
} catch {
|
|
16
|
+
const ta = document.createElement('textarea');
|
|
17
|
+
ta.value = value;
|
|
18
|
+
document.body.appendChild(ta);
|
|
19
|
+
ta.select();
|
|
20
|
+
document.execCommand('copy');
|
|
21
|
+
document.body.removeChild(ta);
|
|
22
|
+
}
|
|
23
|
+
toggleCopied();
|
|
24
|
+
window.setTimeout(() => toggleCopied(), 1200);
|
|
25
|
+
}, [toggleCopied]);
|
|
26
|
+
|
|
27
|
+
return (
|
|
28
|
+
<Box
|
|
29
|
+
radius="xl"
|
|
30
|
+
padding={{ x: 4, y: 2 }}
|
|
31
|
+
className={cn('ring-1 ring-border/50', isStorySection ? 'bg-surface' : 'bg-bg/80 ')}
|
|
32
|
+
>
|
|
33
|
+
<Flex gap={3} align="center" justify="between">
|
|
34
|
+
<FlexItem className="min-w-0">
|
|
35
|
+
<Text size="sm" color="ink" truncate>
|
|
36
|
+
{value}
|
|
37
|
+
</Text>
|
|
38
|
+
</FlexItem>
|
|
39
|
+
|
|
40
|
+
<FlexItem>
|
|
41
|
+
<button
|
|
42
|
+
type="button"
|
|
43
|
+
onClick={onCopy}
|
|
44
|
+
className="shrink-0 inline-flex size-9 items-center justify-center rounded-lg bg-black/5 text-ink hover:bg-black/10 transition-colors cursor-pointer"
|
|
45
|
+
aria-label={copied ? 'Copied' : 'Copy command'}
|
|
46
|
+
title={copied ? 'Copied' : 'Copy'}
|
|
47
|
+
>
|
|
48
|
+
{copied ? <PiCheckBold className="size-4" /> : <PiCopySimpleBold className="size-4" />}
|
|
49
|
+
</button>
|
|
50
|
+
</FlexItem>
|
|
51
|
+
</Flex>
|
|
52
|
+
</Box>
|
|
53
|
+
);
|
|
54
|
+
});
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Box, Flex, FlexItem, Text } from '@/shared/ui';
|
|
3
|
+
import { Links } from '../constants';
|
|
4
|
+
import { Divider } from './Divider';
|
|
5
|
+
|
|
6
|
+
export const Footer = React.memo(() => {
|
|
7
|
+
return (
|
|
8
|
+
<Box className="mt-12 pt-8">
|
|
9
|
+
<Divider className="mb-6" />
|
|
10
|
+
|
|
11
|
+
<Flex
|
|
12
|
+
gap={4}
|
|
13
|
+
align={{ md: 'center' }}
|
|
14
|
+
justify={{ md: 'between' }}
|
|
15
|
+
direction={{ base: 'column', md: 'row' }}
|
|
16
|
+
>
|
|
17
|
+
<FlexItem>
|
|
18
|
+
<Text size="sm" color="muted">
|
|
19
|
+
<span className="font-semibold text-ink">React Scaffold</span>
|
|
20
|
+
<>
|
|
21
|
+
<span className="mx-2">•</span>
|
|
22
|
+
Created by{' '}
|
|
23
|
+
<a
|
|
24
|
+
href={Links.CreatorGithub}
|
|
25
|
+
target="_blank"
|
|
26
|
+
rel="noreferrer"
|
|
27
|
+
className="font-semibold text-ink hover:text-primary transition-colors"
|
|
28
|
+
>
|
|
29
|
+
{Links.CreatorName}
|
|
30
|
+
</a>
|
|
31
|
+
</>
|
|
32
|
+
</Text>
|
|
33
|
+
</FlexItem>
|
|
34
|
+
|
|
35
|
+
<FlexItem>
|
|
36
|
+
<Flex gap={5} className="flex-wrap text-sm font-medium">
|
|
37
|
+
<a
|
|
38
|
+
className="text-muted hover:text-primary"
|
|
39
|
+
href={Links.AppGithub}
|
|
40
|
+
target="_blank"
|
|
41
|
+
rel="noreferrer"
|
|
42
|
+
>
|
|
43
|
+
Project Repo
|
|
44
|
+
</a>
|
|
45
|
+
<a
|
|
46
|
+
className="text-muted hover:text-primary"
|
|
47
|
+
href={Links.CliGithub}
|
|
48
|
+
target="_blank"
|
|
49
|
+
rel="noreferrer"
|
|
50
|
+
>
|
|
51
|
+
CLI Repo
|
|
52
|
+
</a>
|
|
53
|
+
<a
|
|
54
|
+
className="text-muted hover:text-primary"
|
|
55
|
+
href={Links.NpmPackage}
|
|
56
|
+
target="_blank"
|
|
57
|
+
rel="noreferrer"
|
|
58
|
+
>
|
|
59
|
+
NPM Package
|
|
60
|
+
</a>
|
|
61
|
+
|
|
62
|
+
<>
|
|
63
|
+
<span className="text-border">|</span>
|
|
64
|
+
<a
|
|
65
|
+
className="text-muted hover:text-primary"
|
|
66
|
+
href={Links.CreatorLinkedIn}
|
|
67
|
+
target="_blank"
|
|
68
|
+
rel="noreferrer"
|
|
69
|
+
>
|
|
70
|
+
Creator
|
|
71
|
+
</a>
|
|
72
|
+
</>
|
|
73
|
+
</Flex>
|
|
74
|
+
</FlexItem>
|
|
75
|
+
</Flex>
|
|
76
|
+
</Box>
|
|
77
|
+
);
|
|
78
|
+
});
|