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.
- package/bin/index.js +15 -5
- package/package.json +21 -7
- package/scripts/createProject.js +8 -2
- package/templates/{base → base-js}/src/shared/utils/parser.js +1 -1
- package/templates/base-ts/.husky/pre-commit +1 -0
- package/templates/base-ts/.husky/pre-push +0 -0
- package/templates/base-ts/.prettierrc +8 -0
- package/templates/base-ts/.vscode/extensions.json +8 -0
- package/templates/base-ts/.vscode/settings.json +16 -0
- package/templates/base-ts/README.md +165 -0
- package/templates/base-ts/docs/DOCS.md +7 -0
- package/templates/base-ts/eslint.config.js +56 -0
- package/templates/base-ts/index.html +16 -0
- package/templates/base-ts/jsconfig.json +7 -0
- package/templates/base-ts/package.json +69 -0
- package/templates/base-ts/postcss.config.mjs +7 -0
- package/templates/base-ts/public/icons/react.svg +1 -0
- package/templates/base-ts/src/app/APP.md +74 -0
- package/templates/base-ts/src/app/App.tsx +15 -0
- package/templates/base-ts/src/app/Router.tsx +48 -0
- package/templates/base-ts/src/app/index.css +37 -0
- package/templates/base-ts/src/app/main.tsx +13 -0
- package/templates/base-ts/src/app/middlewares/AuthMiddleware.tsx +6 -0
- package/templates/base-ts/src/app/middlewares/index.ts +1 -0
- package/templates/base-ts/src/app/providers/QueryProvider.tsx +75 -0
- package/templates/base-ts/src/app/providers/index.ts +1 -0
- package/templates/base-ts/src/app/routes.registry.ts +9 -0
- package/templates/base-ts/src/features/FEATURES.md +102 -0
- package/templates/base-ts/src/features/sample/components/index.ts +0 -0
- package/templates/base-ts/src/features/sample/constants/index.ts +3 -0
- package/templates/base-ts/src/features/sample/constants/sample.assets.ts +8 -0
- package/templates/base-ts/src/features/sample/constants/sample.navigations.ts +5 -0
- package/templates/base-ts/src/features/sample/constants/sample.queryKeys.ts +3 -0
- package/templates/base-ts/src/features/sample/hooks/index.ts +0 -0
- package/templates/base-ts/src/features/sample/index.ts +1 -0
- package/templates/base-ts/src/features/sample/pages/SamplePage.tsx +7 -0
- package/templates/base-ts/src/features/sample/pages/index.ts +1 -0
- package/templates/base-ts/src/features/sample/sample.routes.ts +13 -0
- package/templates/base-ts/src/features/welcome/components/CodeLine.tsx +59 -0
- package/templates/base-ts/src/features/welcome/components/Divider.tsx +11 -0
- package/templates/base-ts/src/features/welcome/components/Footer.tsx +78 -0
- package/templates/base-ts/src/features/welcome/components/Hero.tsx +131 -0
- package/templates/base-ts/src/features/welcome/components/IconLink.tsx +24 -0
- package/templates/base-ts/src/features/welcome/components/QuickStartPanel.tsx +63 -0
- package/templates/base-ts/src/features/welcome/components/RingSoft.tsx +21 -0
- package/templates/base-ts/src/features/welcome/components/StorySections.tsx +63 -0
- package/templates/base-ts/src/features/welcome/components/WhatYouGet.tsx +49 -0
- package/templates/base-ts/src/features/welcome/components/index.ts +5 -0
- package/templates/base-ts/src/features/welcome/constants/index.ts +2 -0
- package/templates/base-ts/src/features/welcome/constants/welcome.constants.ts +21 -0
- package/templates/base-ts/src/features/welcome/constants/welcome.navigations.ts +3 -0
- package/templates/base-ts/src/features/welcome/index.ts +1 -0
- package/templates/base-ts/src/features/welcome/pages/WelcomePage.tsx +28 -0
- package/templates/base-ts/src/features/welcome/pages/index.ts +1 -0
- package/templates/base-ts/src/features/welcome/welcome.routes.ts +13 -0
- package/templates/base-ts/src/shared/SHARED.md +104 -0
- package/templates/base-ts/src/shared/constants/app.constants.ts +11 -0
- package/templates/base-ts/src/shared/constants/assets.constants.ts +5 -0
- package/templates/base-ts/src/shared/constants/index.ts +2 -0
- package/templates/base-ts/src/shared/contexts/index.ts +0 -0
- package/templates/base-ts/src/shared/hooks/index.ts +3 -0
- package/templates/base-ts/src/shared/hooks/useBooleanState.ts +19 -0
- package/templates/base-ts/src/shared/hooks/useDebounce.ts +17 -0
- package/templates/base-ts/src/shared/hooks/useToggleState.ts +11 -0
- package/templates/base-ts/src/shared/layouts/index.ts +0 -0
- package/templates/base-ts/src/shared/libs/axios.ts +6 -0
- package/templates/base-ts/src/shared/libs/cn.ts +6 -0
- package/templates/base-ts/src/shared/libs/index.ts +2 -0
- package/templates/base-ts/src/shared/theme/index.ts +1 -0
- package/templates/base-ts/src/shared/theme/theme.ts +2149 -0
- package/templates/base-ts/src/shared/types/navigation.ts +9 -0
- package/templates/base-ts/src/shared/types/ui.ts +5 -0
- package/templates/base-ts/src/shared/ui/Box.tsx +153 -0
- package/templates/base-ts/src/shared/ui/Button.tsx +124 -0
- package/templates/base-ts/src/shared/ui/Checkbox.tsx +87 -0
- package/templates/base-ts/src/shared/ui/DropdownMenu.tsx +134 -0
- package/templates/base-ts/src/shared/ui/Flex.tsx +96 -0
- package/templates/base-ts/src/shared/ui/FlexItem.tsx +67 -0
- package/templates/base-ts/src/shared/ui/FormField.tsx +139 -0
- package/templates/base-ts/src/shared/ui/Grid.tsx +96 -0
- package/templates/base-ts/src/shared/ui/GridItem.tsx +67 -0
- package/templates/base-ts/src/shared/ui/Modal.tsx +42 -0
- package/templates/base-ts/src/shared/ui/Scrollable.tsx +48 -0
- package/templates/base-ts/src/shared/ui/Select.tsx +212 -0
- package/templates/base-ts/src/shared/ui/Sheet.tsx +126 -0
- package/templates/base-ts/src/shared/ui/Text.tsx +99 -0
- package/templates/base-ts/src/shared/ui/Toaster.tsx +31 -0
- package/templates/base-ts/src/shared/ui/index.ts +20 -0
- package/templates/base-ts/src/shared/utils/getClassName.ts +8 -0
- package/templates/base-ts/src/shared/utils/index.ts +4 -0
- package/templates/base-ts/src/shared/utils/localStorage.ts +18 -0
- package/templates/base-ts/src/shared/utils/memo.ts +9 -0
- package/templates/base-ts/src/shared/utils/motion.ts +0 -0
- package/templates/base-ts/src/shared/utils/parser.ts +41 -0
- package/templates/base-ts/src/shared/utils/regix.ts +3 -0
- package/templates/base-ts/src/shared/utils/tryCatch.ts +16 -0
- package/templates/base-ts/src/vite-env.d.ts +1 -0
- package/templates/base-ts/tsconfig.json +33 -0
- package/templates/base-ts/tsconfig.node.json +11 -0
- package/templates/base-ts/tsconfig.tsbuildinfo +1 -0
- package/templates/base-ts/vercel.json +3 -0
- package/templates/base-ts/vite.config.d.ts +2 -0
- package/templates/base-ts/vite.config.ts +18 -0
- /package/templates/{base → base-js}/.husky/pre-commit +0 -0
- /package/templates/{base → base-js}/.husky/pre-push +0 -0
- /package/templates/{base → base-js}/.prettierrc +0 -0
- /package/templates/{base → base-js}/.vscode/extensions.json +0 -0
- /package/templates/{base → base-js}/.vscode/settings.json +0 -0
- /package/templates/{base → base-js}/README.md +0 -0
- /package/templates/{base → base-js}/docs/DOCS.md +0 -0
- /package/templates/{base → base-js}/eslint.config.js +0 -0
- /package/templates/{base → base-js}/index.html +0 -0
- /package/templates/{base → base-js}/jsconfig.json +0 -0
- /package/templates/{base → base-js}/package.json +0 -0
- /package/templates/{base → base-js}/postcss.config.mjs +0 -0
- /package/templates/{base → base-js}/public/icons/react.svg +0 -0
- /package/templates/{base → base-js}/src/app/APP.md +0 -0
- /package/templates/{base → base-js}/src/app/App.jsx +0 -0
- /package/templates/{base → base-js}/src/app/Router.jsx +0 -0
- /package/templates/{base → base-js}/src/app/index.css +0 -0
- /package/templates/{base → base-js}/src/app/main.jsx +0 -0
- /package/templates/{base → base-js}/src/app/middlewares/AuthMiddleware.jsx +0 -0
- /package/templates/{base → base-js}/src/app/middlewares/index.js +0 -0
- /package/templates/{base → base-js}/src/app/providers/QueryProvider.jsx +0 -0
- /package/templates/{base → base-js}/src/app/providers/index.js +0 -0
- /package/templates/{base → base-js}/src/app/routes.registry.js +0 -0
- /package/templates/{base → base-js}/src/features/FEATURES.md +0 -0
- /package/templates/{base → base-js}/src/features/sample/components/index.js +0 -0
- /package/templates/{base → base-js}/src/features/sample/constants/index.js +0 -0
- /package/templates/{base → base-js}/src/features/sample/constants/sample.assets.js +0 -0
- /package/templates/{base → base-js}/src/features/sample/constants/sample.constants.js +0 -0
- /package/templates/{base → base-js}/src/features/sample/constants/sample.navigations.js +0 -0
- /package/templates/{base → base-js}/src/features/sample/constants/sample.queryKeys.js +0 -0
- /package/templates/{base → base-js}/src/features/sample/hooks/index.js +0 -0
- /package/templates/{base → base-js}/src/features/sample/index.js +0 -0
- /package/templates/{base → base-js}/src/features/sample/pages/SamplePage.jsx +0 -0
- /package/templates/{base → base-js}/src/features/sample/pages/index.js +0 -0
- /package/templates/{base → base-js}/src/features/sample/sample.context.js +0 -0
- /package/templates/{base → base-js}/src/features/sample/sample.routes.js +0 -0
- /package/templates/{base → base-js}/src/features/welcome/components/CodeLine.jsx +0 -0
- /package/templates/{base → base-js}/src/features/welcome/components/Divider.jsx +0 -0
- /package/templates/{base → base-js}/src/features/welcome/components/Footer.jsx +0 -0
- /package/templates/{base → base-js}/src/features/welcome/components/Hero.jsx +0 -0
- /package/templates/{base → base-js}/src/features/welcome/components/IconLink.jsx +0 -0
- /package/templates/{base → base-js}/src/features/welcome/components/QuickStartPanel.jsx +0 -0
- /package/templates/{base → base-js}/src/features/welcome/components/RingSoft.jsx +0 -0
- /package/templates/{base → base-js}/src/features/welcome/components/StorySections.jsx +0 -0
- /package/templates/{base → base-js}/src/features/welcome/components/WhatYouGet.jsx +0 -0
- /package/templates/{base → base-js}/src/features/welcome/components/index.js +0 -0
- /package/templates/{base → base-js}/src/features/welcome/constants/index.js +0 -0
- /package/templates/{base → base-js}/src/features/welcome/constants/welcome.constants.js +0 -0
- /package/templates/{base → base-js}/src/features/welcome/constants/welcome.navigations.js +0 -0
- /package/templates/{base → base-js}/src/features/welcome/index.js +0 -0
- /package/templates/{base → base-js}/src/features/welcome/pages/WelcomePage.jsx +0 -0
- /package/templates/{base → base-js}/src/features/welcome/pages/index.js +0 -0
- /package/templates/{base → base-js}/src/features/welcome/welcome.routes.js +0 -0
- /package/templates/{base → base-js}/src/shared/SHARED.md +0 -0
- /package/templates/{base → base-js}/src/shared/constants/app.constants.js +0 -0
- /package/templates/{base → base-js}/src/shared/constants/assets.constants.js +0 -0
- /package/templates/{base → base-js}/src/shared/constants/index.js +0 -0
- /package/templates/{base → base-js}/src/shared/contexts/index.js +0 -0
- /package/templates/{base → base-js}/src/shared/hooks/index.js +0 -0
- /package/templates/{base → base-js}/src/shared/hooks/useBooleanState.js +0 -0
- /package/templates/{base → base-js}/src/shared/hooks/useDebounce.js +0 -0
- /package/templates/{base → base-js}/src/shared/hooks/useToggleState.js +0 -0
- /package/templates/{base → base-js}/src/shared/layouts/index.js +0 -0
- /package/templates/{base → base-js}/src/shared/libs/axios.js +0 -0
- /package/templates/{base → base-js}/src/shared/libs/cn.js +0 -0
- /package/templates/{base → base-js}/src/shared/libs/index.js +0 -0
- /package/templates/{base → base-js}/src/shared/theme/index.js +0 -0
- /package/templates/{base → base-js}/src/shared/theme/theme.js +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Box.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Button.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Checkbox.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/DropdownMenu.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Flex.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/FlexItem.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/FormField.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Grid.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/GridItem.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Modal.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Scrollable.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Select.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Sheet.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Text.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/Toaster.jsx +0 -0
- /package/templates/{base → base-js}/src/shared/ui/index.js +0 -0
- /package/templates/{base → base-js}/src/shared/utils/getClassName.js +0 -0
- /package/templates/{base → base-js}/src/shared/utils/index.js +0 -0
- /package/templates/{base → base-js}/src/shared/utils/localStorage.js +0 -0
- /package/templates/{base → base-js}/src/shared/utils/memo.js +0 -0
- /package/templates/{base → base-js}/src/shared/utils/motion.js +0 -0
- /package/templates/{base → base-js}/src/shared/utils/regix.js +0 -0
- /package/templates/{base → base-js}/src/shared/utils/tryCatch.js +0 -0
- /package/templates/{base → base-js}/vercel.json +0 -0
- /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,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 @@
|
|
|
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.
|
|
File without changes
|
|
@@ -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 @@
|
|
|
1
|
+
export * from './theme';
|