create-react-scaffold-cli 1.0.6 → 1.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 (196) hide show
  1. package/bin/index.js +15 -5
  2. package/package.json +21 -7
  3. package/scripts/createProject.js +8 -2
  4. package/templates/{base → base-js}/src/shared/utils/parser.js +1 -1
  5. package/templates/base-ts/.husky/pre-commit +1 -0
  6. package/templates/base-ts/.husky/pre-push +0 -0
  7. package/templates/base-ts/.prettierrc +8 -0
  8. package/templates/base-ts/.vscode/extensions.json +8 -0
  9. package/templates/base-ts/.vscode/settings.json +16 -0
  10. package/templates/base-ts/README.md +165 -0
  11. package/templates/base-ts/docs/DOCS.md +7 -0
  12. package/templates/base-ts/eslint.config.js +56 -0
  13. package/templates/base-ts/index.html +16 -0
  14. package/templates/base-ts/jsconfig.json +7 -0
  15. package/templates/base-ts/package.json +69 -0
  16. package/templates/base-ts/postcss.config.mjs +7 -0
  17. package/templates/base-ts/public/icons/react.svg +1 -0
  18. package/templates/base-ts/src/app/APP.md +74 -0
  19. package/templates/base-ts/src/app/App.tsx +15 -0
  20. package/templates/base-ts/src/app/Router.tsx +48 -0
  21. package/templates/base-ts/src/app/index.css +37 -0
  22. package/templates/base-ts/src/app/main.tsx +13 -0
  23. package/templates/base-ts/src/app/middlewares/AuthMiddleware.tsx +6 -0
  24. package/templates/base-ts/src/app/middlewares/index.ts +1 -0
  25. package/templates/base-ts/src/app/providers/QueryProvider.tsx +75 -0
  26. package/templates/base-ts/src/app/providers/index.ts +1 -0
  27. package/templates/base-ts/src/app/routes.registry.ts +9 -0
  28. package/templates/base-ts/src/features/FEATURES.md +102 -0
  29. package/templates/base-ts/src/features/sample/components/index.ts +0 -0
  30. package/templates/base-ts/src/features/sample/constants/index.ts +3 -0
  31. package/templates/base-ts/src/features/sample/constants/sample.assets.ts +8 -0
  32. package/templates/base-ts/src/features/sample/constants/sample.navigations.ts +5 -0
  33. package/templates/base-ts/src/features/sample/constants/sample.queryKeys.ts +3 -0
  34. package/templates/base-ts/src/features/sample/hooks/index.ts +0 -0
  35. package/templates/base-ts/src/features/sample/index.ts +1 -0
  36. package/templates/base-ts/src/features/sample/pages/SamplePage.tsx +7 -0
  37. package/templates/base-ts/src/features/sample/pages/index.ts +1 -0
  38. package/templates/base-ts/src/features/sample/sample.routes.ts +13 -0
  39. package/templates/base-ts/src/features/welcome/components/CodeLine.tsx +59 -0
  40. package/templates/base-ts/src/features/welcome/components/Divider.tsx +11 -0
  41. package/templates/base-ts/src/features/welcome/components/Footer.tsx +78 -0
  42. package/templates/base-ts/src/features/welcome/components/Hero.tsx +131 -0
  43. package/templates/base-ts/src/features/welcome/components/IconLink.tsx +24 -0
  44. package/templates/base-ts/src/features/welcome/components/QuickStartPanel.tsx +63 -0
  45. package/templates/base-ts/src/features/welcome/components/RingSoft.tsx +21 -0
  46. package/templates/base-ts/src/features/welcome/components/StorySections.tsx +63 -0
  47. package/templates/base-ts/src/features/welcome/components/WhatYouGet.tsx +49 -0
  48. package/templates/base-ts/src/features/welcome/components/index.ts +5 -0
  49. package/templates/base-ts/src/features/welcome/constants/index.ts +2 -0
  50. package/templates/base-ts/src/features/welcome/constants/welcome.constants.ts +21 -0
  51. package/templates/base-ts/src/features/welcome/constants/welcome.navigations.ts +3 -0
  52. package/templates/base-ts/src/features/welcome/index.ts +1 -0
  53. package/templates/base-ts/src/features/welcome/pages/WelcomePage.tsx +28 -0
  54. package/templates/base-ts/src/features/welcome/pages/index.ts +1 -0
  55. package/templates/base-ts/src/features/welcome/welcome.routes.ts +13 -0
  56. package/templates/base-ts/src/shared/SHARED.md +104 -0
  57. package/templates/base-ts/src/shared/constants/app.constants.ts +11 -0
  58. package/templates/base-ts/src/shared/constants/assets.constants.ts +5 -0
  59. package/templates/base-ts/src/shared/constants/index.ts +2 -0
  60. package/templates/base-ts/src/shared/contexts/index.ts +0 -0
  61. package/templates/base-ts/src/shared/hooks/index.ts +3 -0
  62. package/templates/base-ts/src/shared/hooks/useBooleanState.ts +19 -0
  63. package/templates/base-ts/src/shared/hooks/useDebounce.ts +17 -0
  64. package/templates/base-ts/src/shared/hooks/useToggleState.ts +11 -0
  65. package/templates/base-ts/src/shared/layouts/index.ts +0 -0
  66. package/templates/base-ts/src/shared/libs/axios.ts +6 -0
  67. package/templates/base-ts/src/shared/libs/cn.ts +6 -0
  68. package/templates/base-ts/src/shared/libs/index.ts +2 -0
  69. package/templates/base-ts/src/shared/theme/index.ts +1 -0
  70. package/templates/base-ts/src/shared/theme/theme.ts +2149 -0
  71. package/templates/base-ts/src/shared/types/navigation.ts +9 -0
  72. package/templates/base-ts/src/shared/types/ui.ts +5 -0
  73. package/templates/base-ts/src/shared/ui/Box.tsx +153 -0
  74. package/templates/base-ts/src/shared/ui/Button.tsx +124 -0
  75. package/templates/base-ts/src/shared/ui/Checkbox.tsx +87 -0
  76. package/templates/base-ts/src/shared/ui/DropdownMenu.tsx +134 -0
  77. package/templates/base-ts/src/shared/ui/Flex.tsx +96 -0
  78. package/templates/base-ts/src/shared/ui/FlexItem.tsx +67 -0
  79. package/templates/base-ts/src/shared/ui/FormField.tsx +139 -0
  80. package/templates/base-ts/src/shared/ui/Grid.tsx +96 -0
  81. package/templates/base-ts/src/shared/ui/GridItem.tsx +67 -0
  82. package/templates/base-ts/src/shared/ui/Modal.tsx +42 -0
  83. package/templates/base-ts/src/shared/ui/Scrollable.tsx +48 -0
  84. package/templates/base-ts/src/shared/ui/Select.tsx +212 -0
  85. package/templates/base-ts/src/shared/ui/Sheet.tsx +126 -0
  86. package/templates/base-ts/src/shared/ui/Text.tsx +99 -0
  87. package/templates/base-ts/src/shared/ui/Toaster.tsx +31 -0
  88. package/templates/base-ts/src/shared/ui/index.ts +20 -0
  89. package/templates/base-ts/src/shared/utils/getClassName.ts +8 -0
  90. package/templates/base-ts/src/shared/utils/index.ts +4 -0
  91. package/templates/base-ts/src/shared/utils/localStorage.ts +18 -0
  92. package/templates/base-ts/src/shared/utils/memo.ts +9 -0
  93. package/templates/base-ts/src/shared/utils/motion.ts +0 -0
  94. package/templates/base-ts/src/shared/utils/parser.ts +41 -0
  95. package/templates/base-ts/src/shared/utils/regix.ts +3 -0
  96. package/templates/base-ts/src/shared/utils/tryCatch.ts +16 -0
  97. package/templates/base-ts/src/vite-env.d.ts +1 -0
  98. package/templates/base-ts/tsconfig.json +33 -0
  99. package/templates/base-ts/tsconfig.node.json +11 -0
  100. package/templates/base-ts/tsconfig.tsbuildinfo +1 -0
  101. package/templates/base-ts/vercel.json +3 -0
  102. package/templates/base-ts/vite.config.d.ts +2 -0
  103. package/templates/base-ts/vite.config.ts +18 -0
  104. /package/templates/{base → base-js}/.husky/pre-commit +0 -0
  105. /package/templates/{base → base-js}/.husky/pre-push +0 -0
  106. /package/templates/{base → base-js}/.prettierrc +0 -0
  107. /package/templates/{base → base-js}/.vscode/extensions.json +0 -0
  108. /package/templates/{base → base-js}/.vscode/settings.json +0 -0
  109. /package/templates/{base → base-js}/README.md +0 -0
  110. /package/templates/{base → base-js}/docs/DOCS.md +0 -0
  111. /package/templates/{base → base-js}/eslint.config.js +0 -0
  112. /package/templates/{base → base-js}/index.html +0 -0
  113. /package/templates/{base → base-js}/jsconfig.json +0 -0
  114. /package/templates/{base → base-js}/package.json +0 -0
  115. /package/templates/{base → base-js}/postcss.config.mjs +0 -0
  116. /package/templates/{base → base-js}/public/icons/react.svg +0 -0
  117. /package/templates/{base → base-js}/src/app/APP.md +0 -0
  118. /package/templates/{base → base-js}/src/app/App.jsx +0 -0
  119. /package/templates/{base → base-js}/src/app/Router.jsx +0 -0
  120. /package/templates/{base → base-js}/src/app/index.css +0 -0
  121. /package/templates/{base → base-js}/src/app/main.jsx +0 -0
  122. /package/templates/{base → base-js}/src/app/middlewares/AuthMiddleware.jsx +0 -0
  123. /package/templates/{base → base-js}/src/app/middlewares/index.js +0 -0
  124. /package/templates/{base → base-js}/src/app/providers/QueryProvider.jsx +0 -0
  125. /package/templates/{base → base-js}/src/app/providers/index.js +0 -0
  126. /package/templates/{base → base-js}/src/app/routes.registry.js +0 -0
  127. /package/templates/{base → base-js}/src/features/FEATURES.md +0 -0
  128. /package/templates/{base → base-js}/src/features/sample/components/index.js +0 -0
  129. /package/templates/{base → base-js}/src/features/sample/constants/index.js +0 -0
  130. /package/templates/{base → base-js}/src/features/sample/constants/sample.assets.js +0 -0
  131. /package/templates/{base → base-js}/src/features/sample/constants/sample.constants.js +0 -0
  132. /package/templates/{base → base-js}/src/features/sample/constants/sample.navigations.js +0 -0
  133. /package/templates/{base → base-js}/src/features/sample/constants/sample.queryKeys.js +0 -0
  134. /package/templates/{base → base-js}/src/features/sample/hooks/index.js +0 -0
  135. /package/templates/{base → base-js}/src/features/sample/index.js +0 -0
  136. /package/templates/{base → base-js}/src/features/sample/pages/SamplePage.jsx +0 -0
  137. /package/templates/{base → base-js}/src/features/sample/pages/index.js +0 -0
  138. /package/templates/{base → base-js}/src/features/sample/sample.context.js +0 -0
  139. /package/templates/{base → base-js}/src/features/sample/sample.routes.js +0 -0
  140. /package/templates/{base → base-js}/src/features/welcome/components/CodeLine.jsx +0 -0
  141. /package/templates/{base → base-js}/src/features/welcome/components/Divider.jsx +0 -0
  142. /package/templates/{base → base-js}/src/features/welcome/components/Footer.jsx +0 -0
  143. /package/templates/{base → base-js}/src/features/welcome/components/Hero.jsx +0 -0
  144. /package/templates/{base → base-js}/src/features/welcome/components/IconLink.jsx +0 -0
  145. /package/templates/{base → base-js}/src/features/welcome/components/QuickStartPanel.jsx +0 -0
  146. /package/templates/{base → base-js}/src/features/welcome/components/RingSoft.jsx +0 -0
  147. /package/templates/{base → base-js}/src/features/welcome/components/StorySections.jsx +0 -0
  148. /package/templates/{base → base-js}/src/features/welcome/components/WhatYouGet.jsx +0 -0
  149. /package/templates/{base → base-js}/src/features/welcome/components/index.js +0 -0
  150. /package/templates/{base → base-js}/src/features/welcome/constants/index.js +0 -0
  151. /package/templates/{base → base-js}/src/features/welcome/constants/welcome.constants.js +0 -0
  152. /package/templates/{base → base-js}/src/features/welcome/constants/welcome.navigations.js +0 -0
  153. /package/templates/{base → base-js}/src/features/welcome/index.js +0 -0
  154. /package/templates/{base → base-js}/src/features/welcome/pages/WelcomePage.jsx +0 -0
  155. /package/templates/{base → base-js}/src/features/welcome/pages/index.js +0 -0
  156. /package/templates/{base → base-js}/src/features/welcome/welcome.routes.js +0 -0
  157. /package/templates/{base → base-js}/src/shared/SHARED.md +0 -0
  158. /package/templates/{base → base-js}/src/shared/constants/app.constants.js +0 -0
  159. /package/templates/{base → base-js}/src/shared/constants/assets.constants.js +0 -0
  160. /package/templates/{base → base-js}/src/shared/constants/index.js +0 -0
  161. /package/templates/{base → base-js}/src/shared/contexts/index.js +0 -0
  162. /package/templates/{base → base-js}/src/shared/hooks/index.js +0 -0
  163. /package/templates/{base → base-js}/src/shared/hooks/useBooleanState.js +0 -0
  164. /package/templates/{base → base-js}/src/shared/hooks/useDebounce.js +0 -0
  165. /package/templates/{base → base-js}/src/shared/hooks/useToggleState.js +0 -0
  166. /package/templates/{base → base-js}/src/shared/layouts/index.js +0 -0
  167. /package/templates/{base → base-js}/src/shared/libs/axios.js +0 -0
  168. /package/templates/{base → base-js}/src/shared/libs/cn.js +0 -0
  169. /package/templates/{base → base-js}/src/shared/libs/index.js +0 -0
  170. /package/templates/{base → base-js}/src/shared/theme/index.js +0 -0
  171. /package/templates/{base → base-js}/src/shared/theme/theme.js +0 -0
  172. /package/templates/{base → base-js}/src/shared/ui/Box.jsx +0 -0
  173. /package/templates/{base → base-js}/src/shared/ui/Button.jsx +0 -0
  174. /package/templates/{base → base-js}/src/shared/ui/Checkbox.jsx +0 -0
  175. /package/templates/{base → base-js}/src/shared/ui/DropdownMenu.jsx +0 -0
  176. /package/templates/{base → base-js}/src/shared/ui/Flex.jsx +0 -0
  177. /package/templates/{base → base-js}/src/shared/ui/FlexItem.jsx +0 -0
  178. /package/templates/{base → base-js}/src/shared/ui/FormField.jsx +0 -0
  179. /package/templates/{base → base-js}/src/shared/ui/Grid.jsx +0 -0
  180. /package/templates/{base → base-js}/src/shared/ui/GridItem.jsx +0 -0
  181. /package/templates/{base → base-js}/src/shared/ui/Modal.jsx +0 -0
  182. /package/templates/{base → base-js}/src/shared/ui/Scrollable.jsx +0 -0
  183. /package/templates/{base → base-js}/src/shared/ui/Select.jsx +0 -0
  184. /package/templates/{base → base-js}/src/shared/ui/Sheet.jsx +0 -0
  185. /package/templates/{base → base-js}/src/shared/ui/Text.jsx +0 -0
  186. /package/templates/{base → base-js}/src/shared/ui/Toaster.jsx +0 -0
  187. /package/templates/{base → base-js}/src/shared/ui/index.js +0 -0
  188. /package/templates/{base → base-js}/src/shared/utils/getClassName.js +0 -0
  189. /package/templates/{base → base-js}/src/shared/utils/index.js +0 -0
  190. /package/templates/{base → base-js}/src/shared/utils/localStorage.js +0 -0
  191. /package/templates/{base → base-js}/src/shared/utils/memo.js +0 -0
  192. /package/templates/{base → base-js}/src/shared/utils/motion.js +0 -0
  193. /package/templates/{base → base-js}/src/shared/utils/regix.js +0 -0
  194. /package/templates/{base → base-js}/src/shared/utils/tryCatch.js +0 -0
  195. /package/templates/{base → base-js}/vercel.json +0 -0
  196. /package/templates/{base → base-js}/vite.config.js +0 -0
@@ -0,0 +1,63 @@
1
+
2
+ import { Divider } from './Divider';
3
+ import { CodeLine } from './CodeLine';
4
+ import { Box, Flex, FlexItem, Grid, GridItem, Text } from '@/shared/ui';
5
+ import { Commands } from '../constants';
6
+
7
+ function Block({ title, body }: { title: string; body: string }) {
8
+ return (
9
+ <Box>
10
+ <Text className="text-sm font-bold tracking-tight">{title}</Text>
11
+ <Text className="mt-2 text-muted leading-relaxed">{body}</Text>
12
+ </Box>
13
+ );
14
+ }
15
+
16
+ export function StorySections() {
17
+ return (
18
+ <Grid gap={{ base: 10, md: 12 }} columns={{ base: 1, md: 2 }}>
19
+ <GridItem>
20
+ <Flex gap={2} direction="column">
21
+ <FlexItem>
22
+ <Text
23
+ weight="black"
24
+ font="plus-jakarta-sans"
25
+ size={{ base: '2xl', md: '3xl' }}
26
+ className="tracking-tight bg-linear-to-r from-primary to-ink bg-clip-text text-transparent"
27
+ >
28
+ Why this exists
29
+ </Text>
30
+ </FlexItem>
31
+
32
+ <FlexItem className="max-w-2xl">
33
+ <Text size="base" color="muted">
34
+ Less starter bloat, more clarity. You get patterns that keep apps maintainable as
35
+ teams grow.
36
+ </Text>
37
+ </FlexItem>
38
+ </Flex>
39
+ </GridItem>
40
+ <GridItem className="space-y-7">
41
+ <Block
42
+ title="Project purpose"
43
+ body="React Scaffold helps teams start real apps fast—with structure, shared UI primitives, and a clean foundation for long-term maintainability."
44
+ />
45
+ <Divider />
46
+ <Block
47
+ title="Problem it solves"
48
+ body="Most starters don’t scale. This scaffold enforces patterns so features stay isolated, UI stays consistent, and refactoring remains safe."
49
+ />
50
+ <Divider />
51
+ <Box>
52
+ <Text size="sm" className="font-bold tracking-tight">
53
+ How to start
54
+ </Text>
55
+ <Box className="mt-3 space-y-3">
56
+ <CodeLine isStorySection value={Commands.Scaffold} />
57
+ <CodeLine isStorySection value={Commands.Run} />
58
+ </Box>
59
+ </Box>
60
+ </GridItem>
61
+ </Grid>
62
+ );
63
+ }
@@ -0,0 +1,49 @@
1
+ import { memo } from 'react';
2
+ import { SOLUTIONS } from '../constants';
3
+ import { Flex, FlexItem, Text } from '@/shared/ui';
4
+
5
+ export const WhatYouGet = memo(() => {
6
+ return (
7
+ <Flex gap={2} direction="column">
8
+ <FlexItem>
9
+ <Text
10
+ weight="black"
11
+ font="plus-jakarta-sans"
12
+ size={{ base: '2xl', md: '3xl' }}
13
+ className="tracking-tight bg-linear-to-r from-primary to-ink bg-clip-text text-transparent"
14
+ >
15
+ What you get
16
+ </Text>
17
+ </FlexItem>
18
+
19
+ <FlexItem className="max-w-2xl">
20
+ <Text size="base" color="muted">
21
+ A real-world scaffold: structure + UI foundations + modern stack.
22
+ </Text>
23
+ </FlexItem>
24
+ <FlexItem>
25
+ <Flex gap={2} className="mt-4 flex-wrap">
26
+ {SOLUTIONS.map((x) => (
27
+ <Flex
28
+ gap={2}
29
+ key={x.label}
30
+ align="center"
31
+ className="inline-flex items-center gap-2 rounded-full bg-surface/80 px-4 py-2"
32
+ >
33
+ <FlexItem>
34
+ <Text size="sm" color="muted">
35
+ {x.label}:
36
+ </Text>
37
+ </FlexItem>
38
+ <FlexItem>
39
+ <Text color="ink" weight="semibold">
40
+ {x.value}
41
+ </Text>
42
+ </FlexItem>
43
+ </Flex>
44
+ ))}
45
+ </Flex>
46
+ </FlexItem>
47
+ </Flex>
48
+ );
49
+ });
@@ -0,0 +1,5 @@
1
+ export { Hero } from './Hero';
2
+ export { Divider } from './Divider';
3
+ export { WhatYouGet } from './WhatYouGet';
4
+ export { StorySections } from './StorySections';
5
+ export { Footer } from './Footer';
@@ -0,0 +1,2 @@
1
+ export * from './welcome.constants';
2
+ export { WelcomeNavigation } from './welcome.navigations';
@@ -0,0 +1,21 @@
1
+ export const Links = {
2
+ CliGithub: 'https://github.com/arsalanirshad57/create-react-scaffold-cli',
3
+ AppGithub: 'https://github.com/arsalanirshad57/react-scaffold-app',
4
+ NpmPackage: 'https://www.npmjs.com/package/create-react-scaffold-cli',
5
+
6
+ CreatorName: 'Muhammad Arsalan',
7
+ CreatorGithub: 'https://github.com/arsalanirshad57',
8
+ CreatorLinkedIn: 'https://www.linkedin.com/in/heyarsalanhere/',
9
+ } as const;
10
+
11
+ export const Commands = {
12
+ Scaffold: 'npx create-react-scaffold-cli',
13
+ Run: 'npm run dev',
14
+ } as const;
15
+
16
+ export const SOLUTIONS = [
17
+ { label: 'Architecture', value: 'Feature-first' },
18
+ { label: 'UI System', value: 'Primitives + Radix' },
19
+ { label: 'Data', value: 'React Query + Axios' },
20
+ { label: 'Tooling', value: 'ESLint + Prettier + Husky' },
21
+ ] as const;
@@ -0,0 +1,3 @@
1
+ export const WelcomeNavigation = {
2
+ Root: '/welcome',
3
+ } as const;
@@ -0,0 +1 @@
1
+ export { welcomeRoutes } from './welcome.routes';
@@ -0,0 +1,28 @@
1
+ import { memo } from 'react';
2
+ import { Box } from '@/shared/ui';
3
+ import { Divider, Footer, Hero, StorySections, WhatYouGet } from '../components';
4
+
5
+ const WelcomePage = memo(() => {
6
+ return (
7
+ <Box className="min-h-screen bg-bg text-ink">
8
+ <Box
9
+ className="mx-auto max-w-6xl"
10
+ padding={{ x: { base: 4, md: 6 }, y: { base: 10, md: 14 } }}
11
+ >
12
+ <Hero />
13
+
14
+ <Divider className="my-10 md:my-12" />
15
+
16
+ <WhatYouGet />
17
+
18
+ <Divider className="my-10 md:my-12" />
19
+
20
+ <StorySections />
21
+
22
+ <Footer />
23
+ </Box>
24
+ </Box>
25
+ );
26
+ });
27
+
28
+ export default WelcomePage;
@@ -0,0 +1 @@
1
+ export { default as WelcomePage } from './WelcomePage';
@@ -0,0 +1,13 @@
1
+ import { AppRoute } from '@/shared/types/navigation';
2
+ import { Layouts } from '@/shared/constants';
3
+ import { WelcomePage } from './pages';
4
+ import { WelcomeNavigation } from './constants';
5
+
6
+ export const welcomeRoutes: AppRoute[] = [
7
+ {
8
+ path: WelcomeNavigation.Root,
9
+ element: WelcomePage,
10
+ protected: false,
11
+ layout: Layouts.None,
12
+ },
13
+ ];
@@ -0,0 +1,104 @@
1
+ # Shared Module
2
+
3
+ ## Purpose
4
+
5
+ The `shared` folder contains **cross-feature reusable code**.
6
+
7
+ It exists to prevent duplication — not to become a dumping ground.
8
+
9
+ > Shared code must earn its place.
10
+
11
+ ---
12
+
13
+ ## What Belongs in Shared
14
+
15
+ Only code that is:
16
+
17
+ - Used by **multiple features**
18
+ - **Stateless or generic**
19
+ - Independent of business rules
20
+
21
+ ---
22
+
23
+ ## Folder Structure
24
+
25
+ ```txt
26
+ shared/
27
+ assets/ # Global images/icons
28
+ constants/ # App-wide constants
29
+ contexts/ # Truly global contexts
30
+ hooks/ # Reusable generic hooks
31
+ layouts/ # Application layouts
32
+ libs/ # Third-party wrappers (axios, query)
33
+ theme/ # Theme configuration
34
+ ui/ # Design system components
35
+ utils/ # Pure utility functions
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Rules
41
+
42
+ ### ✅ Allowed
43
+
44
+ - UI primitives (Button, Modal)
45
+ - Generic hooks (useDebounce)
46
+ - Axios/query setup
47
+ - Theme tokens
48
+
49
+ ### ❌ Not Allowed
50
+
51
+ - Feature logic
52
+ - Business rules
53
+ - Feature-specific constants
54
+ - Feature state
55
+
56
+ ---
57
+
58
+ ## Import Rules
59
+
60
+ ```js
61
+ // ✅ Allowed
62
+ import { axios } from '@/shared/libs';
63
+ import { cn } from '@/shared/utils';
64
+
65
+ // ❌ Not Allowed
66
+ import { authQueryKeys } from '@/features/auth';
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Constants Policy
72
+
73
+ Shared constants should be:
74
+
75
+ - Truly global
76
+ - Stable
77
+ - Rarely changed
78
+
79
+ Examples:
80
+
81
+ - Pagination defaults
82
+ - Environment keys
83
+ - Generic route params
84
+
85
+ ---
86
+
87
+ ## Contexts
88
+
89
+ Global contexts should be rare.
90
+
91
+ Before adding one, ask:
92
+
93
+ 1. Is this needed by multiple unrelated features?
94
+ 2. Can this live inside a feature instead?
95
+
96
+ If unsure — **do not add it here**.
97
+
98
+ ---
99
+
100
+ ## Philosophy
101
+
102
+ Shared code is a **dependency magnet**.
103
+
104
+ The smaller it stays, the healthier the system remains.
@@ -0,0 +1,11 @@
1
+ export const ENV = {
2
+ BACKEND_URL: import.meta.env.VITE_BACKEND_URL as string,
3
+ };
4
+
5
+ export const Layouts = {
6
+ Dashboard: 'dashboard',
7
+ Auth: 'auth',
8
+ None: 'none',
9
+ } as const;
10
+
11
+ export type LayoutType = typeof Layouts[keyof typeof Layouts];
@@ -0,0 +1,5 @@
1
+ export const AppAssets = {
2
+ Logos: {},
3
+ Images: {},
4
+ Icons: {},
5
+ } as const;
@@ -0,0 +1,2 @@
1
+ export * from './app.constants';
2
+ export { AppAssets } from './assets.constants';
File without changes
@@ -0,0 +1,3 @@
1
+ export { useBooleanState } from './useBooleanState';
2
+ export { useDebounce } from './useDebounce';
3
+ export { useToggleState } from './useToggleState';
@@ -0,0 +1,19 @@
1
+ import { useCallback, useState } from 'react';
2
+
3
+ export const useBooleanState = (initialValue: boolean = false): [boolean, () => void, () => void, () => void] => {
4
+ const [value, setValue] = useState(initialValue);
5
+
6
+ const toggle = useCallback(() => {
7
+ setValue((v) => !v);
8
+ }, []);
9
+
10
+ const setToTrue = useCallback(() => {
11
+ setValue(true);
12
+ }, []);
13
+
14
+ const setToFalse = useCallback(() => {
15
+ setValue(false);
16
+ }, []);
17
+
18
+ return [value, setToTrue, setToFalse, toggle];
19
+ };
@@ -0,0 +1,17 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ export const useDebounce = <T>(value: T, delay: number): T => {
4
+ const [debounceValue, setDoebounceValue] = useState<T>(value);
5
+
6
+ useEffect(() => {
7
+ const handler = setTimeout(() => {
8
+ setDoebounceValue(value);
9
+ }, delay);
10
+
11
+ return () => {
12
+ clearTimeout(handler);
13
+ };
14
+ }, [value, delay]);
15
+
16
+ return debounceValue;
17
+ };
@@ -0,0 +1,11 @@
1
+ import { useCallback, useState } from 'react';
2
+
3
+ export const useToggleState = (initialValue: boolean = false): [boolean, () => void] => {
4
+ const [state, setState] = useState(initialValue);
5
+
6
+ const toggle = useCallback(() => {
7
+ setState((v) => !v);
8
+ }, []);
9
+
10
+ return [state, toggle];
11
+ };
File without changes
@@ -0,0 +1,6 @@
1
+ import baseAxios from 'axios';
2
+ import { ENV } from '../constants/app.constants';
3
+
4
+ export const axios = baseAxios.create({
5
+ baseURL: ENV.BACKEND_URL,
6
+ });
@@ -0,0 +1,6 @@
1
+ import { clsx, type ClassValue } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(...inputs));
6
+ }
@@ -0,0 +1,2 @@
1
+ export { axios } from './axios';
2
+ export { cn } from './cn';
@@ -0,0 +1 @@
1
+ export * from './theme';