create-lumen 1.1.3 → 1.2.0-beta.1

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 (247) hide show
  1. package/README.md +43 -35
  2. package/package.json +8 -2
  3. package/src/configure.js +29 -15
  4. package/src/css.js +73 -14
  5. package/src/dependencies.js +8 -3
  6. package/src/format.js +28 -0
  7. package/src/injector.js +131 -28
  8. package/src/main.js +17 -1
  9. package/src/readme.js +65 -22
  10. package/templates/architectures/component-based/main.tsx +1 -1
  11. package/templates/architectures/component-based/src/App.jsx +6 -4
  12. package/templates/architectures/component-based/src/App.tsx +6 -4
  13. package/templates/architectures/component-based/src/components/common/Button.jsx +5 -4
  14. package/templates/architectures/component-based/src/components/common/Button.tsx +5 -4
  15. package/templates/architectures/component-based/src/hooks/useApp.js +10 -0
  16. package/templates/architectures/component-based/src/hooks/useApp.ts +10 -0
  17. package/templates/architectures/component-based/src/hooks/useLocalStorage.ts +5 -5
  18. package/templates/architectures/component-based/src/layouts/MainLayout.jsx +12 -6
  19. package/templates/architectures/component-based/src/layouts/MainLayout.tsx +12 -6
  20. package/templates/architectures/component-based/src/pages/Home/Home.jsx +6 -2
  21. package/templates/architectures/component-based/src/pages/Home/Home.tsx +6 -2
  22. package/templates/architectures/component-based/src/providers/AppProvider.jsx +20 -0
  23. package/templates/architectures/component-based/src/providers/AppProvider.tsx +24 -0
  24. package/templates/architectures/component-based/src/providers/appcontext.js +3 -0
  25. package/templates/architectures/component-based/src/providers/appcontext.ts +8 -0
  26. package/templates/architectures/{feature-based → component-based}/src/types/index.js +7 -0
  27. package/templates/architectures/{feature-based → component-based}/src/types/index.ts +5 -0
  28. package/templates/architectures/component-based/src/utils/cn.ts +3 -1
  29. package/templates/architectures/feature-based/main.jsx +1 -1
  30. package/templates/architectures/feature-based/main.tsx +2 -2
  31. package/templates/architectures/feature-based/scripts/create-feature.mjs +2 -2
  32. package/templates/architectures/feature-based/src/app/App.jsx +15 -5
  33. package/templates/architectures/feature-based/src/app/App.tsx +15 -5
  34. package/templates/architectures/feature-based/src/app/contexts/themecontext.js +3 -0
  35. package/templates/architectures/feature-based/src/app/contexts/themecontext.ts +8 -0
  36. package/templates/architectures/feature-based/src/app/hooks/useTheme.js +10 -0
  37. package/templates/architectures/feature-based/src/app/hooks/useTheme.ts +10 -0
  38. package/templates/architectures/feature-based/src/app/providers/ThemeProvider.jsx +17 -2
  39. package/templates/architectures/feature-based/src/app/providers/ThemeProvider.tsx +20 -3
  40. package/templates/architectures/feature-based/src/features/home/pages/HomePage.jsx +18 -5
  41. package/templates/architectures/feature-based/src/features/home/pages/HomePage.tsx +18 -5
  42. package/templates/architectures/feature-based/src/shared/components/ui/Button.jsx +31 -0
  43. package/templates/architectures/feature-based/src/shared/components/ui/Button.tsx +36 -0
  44. package/templates/architectures/feature-based/src/{hooks → shared/hooks}/useLocalStorage.ts +5 -5
  45. package/templates/architectures/feature-based/src/shared/layouts/.gitkeep +0 -0
  46. package/templates/architectures/feature-based/src/shared/stores/.gitkeep +0 -0
  47. package/templates/architectures/feature-based/src/shared/styles/.gitkeep +0 -0
  48. package/templates/architectures/feature-based/src/shared/types/index.js +20 -0
  49. package/templates/architectures/feature-based/src/shared/types/index.ts +16 -0
  50. package/templates/architectures/feature-based/src/shared/utils/cn.ts +5 -0
  51. package/templates/conditional/axios/component-based/src/config/axios.config.js +7 -0
  52. package/templates/conditional/axios/component-based/src/config/axios.config.ts +7 -0
  53. package/templates/conditional/axios/component-based/src/services/axios.client.js +24 -0
  54. package/templates/conditional/axios/component-based/src/services/axios.client.ts +24 -0
  55. package/templates/conditional/axios/component-based/src/services/user.service.js +33 -0
  56. package/templates/conditional/axios/component-based/src/services/user.service.ts +29 -0
  57. package/templates/conditional/axios/feature-based/src/features/home/services/user.service.js +33 -0
  58. package/templates/conditional/axios/feature-based/src/features/home/services/user.service.ts +29 -0
  59. package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.client.js +24 -0
  60. package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.client.ts +24 -0
  61. package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.config.js +7 -0
  62. package/templates/conditional/axios/feature-based/src/shared/lib/axios/api.config.ts +7 -0
  63. package/templates/conditional/axios/feature-based/src/shared/lib/axios/index.js +1 -0
  64. package/templates/conditional/axios/feature-based/src/shared/lib/axios/index.ts +1 -0
  65. package/templates/conditional/fetch/component-based/src/config/api.config.js +7 -0
  66. package/templates/conditional/fetch/component-based/src/config/api.config.ts +7 -0
  67. package/templates/conditional/fetch/component-based/src/services/api.client.js +51 -0
  68. package/templates/conditional/fetch/component-based/src/services/api.client.ts +55 -0
  69. package/templates/conditional/fetch/component-based/src/services/user.service.js +33 -0
  70. package/templates/conditional/fetch/component-based/src/services/user.service.ts +29 -0
  71. package/templates/conditional/fetch/feature-based/src/features/home/services/user.service.js +33 -0
  72. package/templates/conditional/fetch/feature-based/src/features/home/services/user.service.ts +29 -0
  73. package/templates/conditional/fetch/feature-based/src/shared/api/api.client.js +51 -0
  74. package/templates/conditional/fetch/feature-based/src/shared/api/api.client.ts +55 -0
  75. package/templates/conditional/fetch/feature-based/src/shared/api/api.config.js +7 -0
  76. package/templates/conditional/fetch/feature-based/src/shared/api/api.config.ts +7 -0
  77. package/templates/conditional/fetch/feature-based/src/shared/api/index.js +1 -0
  78. package/templates/conditional/fetch/feature-based/src/shared/api/index.ts +1 -0
  79. package/templates/conditional/formatter/oxfmt/.oxfmtrc.json +1 -1
  80. package/templates/conditional/formatter/prettier/.prettierrc +2 -2
  81. package/templates/conditional/icons/huge/component-based/bootstrap/src/pages/Home/Home.jsx +20 -0
  82. package/templates/conditional/icons/huge/component-based/bootstrap/src/pages/Home/Home.tsx +20 -0
  83. package/templates/conditional/icons/huge/component-based/src/pages/Home/Home.jsx +26 -10
  84. package/templates/conditional/icons/huge/component-based/src/pages/Home/Home.tsx +26 -10
  85. package/templates/conditional/icons/huge/component-based/tailwind/src/pages/Home/Home.jsx +20 -0
  86. package/templates/conditional/icons/huge/component-based/tailwind/src/pages/Home/Home.tsx +20 -0
  87. package/templates/conditional/icons/huge/feature-based/bootstrap/src/features/home/pages/HomePage.jsx +20 -0
  88. package/templates/conditional/icons/huge/feature-based/bootstrap/src/features/home/pages/HomePage.tsx +20 -0
  89. package/templates/conditional/icons/huge/feature-based/src/features/home/pages/HomePage.jsx +27 -11
  90. package/templates/conditional/icons/huge/feature-based/src/features/home/pages/HomePage.tsx +27 -11
  91. package/templates/conditional/icons/huge/feature-based/tailwind/src/features/home/pages/HomePage.jsx +20 -0
  92. package/templates/conditional/icons/huge/feature-based/tailwind/src/features/home/pages/HomePage.tsx +20 -0
  93. package/templates/conditional/icons/lucide/component-based/bootstrap/src/pages/Home/Home.jsx +19 -0
  94. package/templates/conditional/icons/lucide/component-based/bootstrap/src/pages/Home/Home.tsx +19 -0
  95. package/templates/conditional/icons/lucide/component-based/src/pages/Home/Home.jsx +25 -10
  96. package/templates/conditional/icons/lucide/component-based/src/pages/Home/Home.tsx +25 -10
  97. package/templates/conditional/icons/lucide/component-based/tailwind/src/pages/Home/Home.jsx +19 -0
  98. package/templates/conditional/icons/lucide/component-based/tailwind/src/pages/Home/Home.tsx +19 -0
  99. package/templates/conditional/icons/lucide/feature-based/bootstrap/src/features/home/pages/HomePage.jsx +19 -0
  100. package/templates/conditional/icons/lucide/feature-based/bootstrap/src/features/home/pages/HomePage.tsx +19 -0
  101. package/templates/conditional/icons/lucide/feature-based/src/features/home/pages/HomePage.jsx +26 -11
  102. package/templates/conditional/icons/lucide/feature-based/src/features/home/pages/HomePage.tsx +26 -11
  103. package/templates/conditional/icons/lucide/feature-based/tailwind/src/features/home/pages/HomePage.jsx +19 -0
  104. package/templates/conditional/icons/lucide/feature-based/tailwind/src/features/home/pages/HomePage.tsx +19 -0
  105. package/templates/conditional/linting/eslint/eslint.config.js +24 -2
  106. package/templates/conditional/linting/eslint/eslint.config.ts +25 -2
  107. package/templates/conditional/router/component-based/bootstrap/src/layouts/MainLayout.jsx +17 -0
  108. package/templates/conditional/router/component-based/bootstrap/src/layouts/MainLayout.tsx +17 -0
  109. package/templates/conditional/router/component-based/src/App.jsx +4 -5
  110. package/templates/conditional/router/component-based/src/App.tsx +4 -5
  111. package/templates/conditional/router/component-based/src/layouts/MainLayout.jsx +39 -0
  112. package/templates/conditional/router/component-based/src/layouts/MainLayout.tsx +39 -0
  113. package/templates/conditional/router/component-based/src/router/guards/AuthGuard.jsx +8 -0
  114. package/templates/conditional/router/component-based/src/router/guards/AuthGuard.tsx +14 -0
  115. package/templates/conditional/router/component-based/src/router/guards/GuestGuard.jsx +8 -0
  116. package/templates/conditional/router/component-based/src/router/guards/GuestGuard.tsx +14 -0
  117. package/templates/conditional/router/component-based/src/router/index.jsx +44 -0
  118. package/templates/conditional/router/component-based/src/router/index.tsx +44 -0
  119. package/templates/conditional/router/component-based/tailwind/src/layouts/MainLayout.jsx +17 -0
  120. package/templates/conditional/router/component-based/tailwind/src/layouts/MainLayout.tsx +17 -0
  121. package/templates/conditional/router/feature-based/bootstrap/src/shared/layouts/RootLayout.jsx +9 -0
  122. package/templates/conditional/router/feature-based/bootstrap/src/shared/layouts/RootLayout.tsx +9 -0
  123. package/templates/conditional/router/feature-based/src/app/App.jsx +6 -2
  124. package/templates/conditional/router/feature-based/src/app/App.tsx +6 -2
  125. package/templates/conditional/router/feature-based/src/app/router/guards/AuthGuard.jsx +8 -0
  126. package/templates/conditional/router/feature-based/src/app/router/guards/AuthGuard.tsx +14 -0
  127. package/templates/conditional/router/feature-based/src/app/router/guards/RoleGuard.jsx +8 -0
  128. package/templates/conditional/router/feature-based/src/app/router/guards/RoleGuard.tsx +15 -0
  129. package/templates/conditional/router/feature-based/src/app/router/index.jsx +16 -0
  130. package/templates/conditional/router/feature-based/src/app/router/index.tsx +16 -0
  131. package/templates/conditional/router/feature-based/src/app/router/routes/auth.routes.jsx +18 -0
  132. package/templates/conditional/router/feature-based/src/app/router/routes/auth.routes.tsx +18 -0
  133. package/templates/conditional/router/feature-based/src/app/router/routes/home.routes.jsx +8 -0
  134. package/templates/conditional/router/feature-based/src/app/router/routes/home.routes.tsx +8 -0
  135. package/templates/conditional/router/feature-based/src/shared/layouts/RootLayout.jsx +17 -0
  136. package/templates/conditional/router/feature-based/src/shared/layouts/RootLayout.tsx +17 -0
  137. package/templates/conditional/router/feature-based/tailwind/src/shared/layouts/RootLayout.jsx +9 -0
  138. package/templates/conditional/router/feature-based/tailwind/src/shared/layouts/RootLayout.tsx +9 -0
  139. package/templates/conditional/state/redux/component-based/src/pages/Home/counterSlice.ts +9 -3
  140. package/templates/conditional/state/redux/component-based/src/{context → providers}/StoreProvider.jsx +0 -1
  141. package/templates/conditional/state/redux/component-based/src/{context → providers}/StoreProvider.tsx +2 -2
  142. package/templates/conditional/state/redux/component-based/src/store/hooks.ts +4 -2
  143. package/templates/conditional/state/redux/component-based/src/store/index.ts +2 -2
  144. package/templates/conditional/state/redux/feature-based/src/app/providers/StoreProvider.jsx +1 -2
  145. package/templates/conditional/state/redux/feature-based/src/app/providers/StoreProvider.tsx +3 -3
  146. package/templates/conditional/state/redux/feature-based/src/features/home/store/counterSlice.ts +9 -3
  147. package/templates/conditional/state/redux/feature-based/src/shared/stores/hooks.ts +6 -0
  148. package/templates/conditional/state/redux/feature-based/src/{stores → shared/stores}/index.ts +2 -2
  149. package/templates/conditional/state/zustand/component-based/src/store/useCounterStore.ts +8 -1
  150. package/templates/conditional/state/zustand/feature-based/src/stores/useCounterStore.ts +8 -1
  151. package/templates/conditional/testing/jest/babel.config.cjs +7 -0
  152. package/templates/conditional/testing/jest/component-based/src/__tests__/App.test.jsx +10 -0
  153. package/templates/conditional/testing/jest/component-based/src/__tests__/App.test.tsx +11 -0
  154. package/templates/conditional/testing/jest/{src → feature-based/src}/__tests__/App.test.jsx +2 -1
  155. package/templates/conditional/testing/jest/feature-based/src/__tests__/App.test.tsx +11 -0
  156. package/templates/conditional/testing/jest/jest.config.js +2 -3
  157. package/templates/conditional/testing/jest/jest.config.ts +6 -4
  158. package/templates/conditional/testing/jest/jest.setup.js +6 -0
  159. package/templates/conditional/testing/jest/jest.setup.ts +6 -0
  160. package/templates/conditional/testing/vitest/component-based/src/__tests__/App.test.jsx +10 -0
  161. package/templates/conditional/testing/{jest → vitest/component-based}/src/__tests__/App.test.tsx +2 -1
  162. package/templates/css/bootstrap/src/themes.css +14 -0
  163. package/templates/css/component-styles/bootstrap/component-based/src/components/common/Button.jsx +17 -0
  164. package/templates/css/component-styles/bootstrap/component-based/src/components/common/Button.tsx +22 -0
  165. package/templates/css/component-styles/bootstrap/component-based/src/layouts/MainLayout.jsx +15 -0
  166. package/templates/css/component-styles/bootstrap/component-based/src/layouts/MainLayout.tsx +19 -0
  167. package/templates/css/component-styles/bootstrap/component-based/src/pages/Home/Home.jsx +13 -0
  168. package/templates/css/component-styles/bootstrap/component-based/src/pages/Home/Home.tsx +13 -0
  169. package/templates/css/component-styles/bootstrap/feature-based/src/app/App.jsx +9 -0
  170. package/templates/css/component-styles/bootstrap/feature-based/src/app/App.tsx +9 -0
  171. package/templates/css/component-styles/bootstrap/feature-based/src/features/home/pages/HomePage.jsx +13 -0
  172. package/templates/css/component-styles/bootstrap/feature-based/src/features/home/pages/HomePage.tsx +13 -0
  173. package/templates/css/component-styles/bootstrap/feature-based/src/shared/components/ui/Button.jsx +17 -0
  174. package/templates/css/component-styles/bootstrap/feature-based/src/shared/components/ui/Button.tsx +22 -0
  175. package/templates/{architectures/feature-based/src/components/ui → css/component-styles/tailwind/component-based/src/components/common}/Button.jsx +1 -3
  176. package/templates/{architectures/feature-based/src/components/ui → css/component-styles/tailwind/component-based/src/components/common}/Button.tsx +1 -3
  177. package/templates/css/component-styles/tailwind/component-based/src/layouts/MainLayout.jsx +15 -0
  178. package/templates/css/component-styles/tailwind/component-based/src/layouts/MainLayout.tsx +19 -0
  179. package/templates/css/component-styles/tailwind/component-based/src/pages/Home/Home.jsx +13 -0
  180. package/templates/css/component-styles/tailwind/component-based/src/pages/Home/Home.tsx +13 -0
  181. package/templates/css/component-styles/tailwind/feature-based/src/app/App.jsx +9 -0
  182. package/templates/css/component-styles/tailwind/feature-based/src/app/App.tsx +9 -0
  183. package/templates/css/component-styles/tailwind/feature-based/src/features/home/pages/HomePage.jsx +13 -0
  184. package/templates/css/component-styles/tailwind/feature-based/src/features/home/pages/HomePage.tsx +13 -0
  185. package/templates/css/component-styles/tailwind/feature-based/src/shared/components/ui/Button.jsx +21 -0
  186. package/templates/css/component-styles/tailwind/feature-based/src/shared/components/ui/Button.tsx +26 -0
  187. package/templates/css/none/src/{index.css → main.css} +2 -0
  188. package/templates/css/none/src/themes.css +19 -0
  189. package/templates/css/tailwind/src/themes.css +9 -0
  190. package/templates/architectures/component-based/src/config/constants.js +0 -2
  191. package/templates/architectures/component-based/src/config/constants.ts +0 -2
  192. package/templates/architectures/component-based/src/config/routes.js +0 -7
  193. package/templates/architectures/component-based/src/config/routes.ts +0 -7
  194. package/templates/architectures/component-based/src/context/AppContext.jsx +0 -13
  195. package/templates/architectures/component-based/src/context/AppContext.tsx +0 -13
  196. package/templates/architectures/component-based/src/hooks/index.js +0 -1
  197. package/templates/architectures/component-based/src/hooks/index.ts +0 -1
  198. package/templates/architectures/component-based/src/layouts/index.js +0 -1
  199. package/templates/architectures/component-based/src/layouts/index.ts +0 -1
  200. package/templates/architectures/component-based/src/routes/index.jsx +0 -11
  201. package/templates/architectures/component-based/src/routes/index.tsx +0 -11
  202. package/templates/architectures/component-based/src/styles/globals.css +0 -7
  203. package/templates/architectures/component-based/src/utils/index.js +0 -1
  204. package/templates/architectures/component-based/src/utils/index.ts +0 -1
  205. package/templates/architectures/feature-based/src/config/constants.js +0 -2
  206. package/templates/architectures/feature-based/src/config/constants.ts +0 -2
  207. package/templates/architectures/feature-based/src/hooks/index.js +0 -1
  208. package/templates/architectures/feature-based/src/hooks/index.ts +0 -1
  209. package/templates/architectures/feature-based/src/utils/cn.ts +0 -6
  210. package/templates/architectures/feature-based/src/utils/index.js +0 -1
  211. package/templates/architectures/feature-based/src/utils/index.ts +0 -1
  212. package/templates/conditional/axios/component-based/src/services/axios.jsx +0 -19
  213. package/templates/conditional/axios/component-based/src/services/axios.ts +0 -19
  214. package/templates/conditional/axios/component-based/src/services/index.js +0 -1
  215. package/templates/conditional/axios/component-based/src/services/index.ts +0 -1
  216. package/templates/conditional/axios/feature-based/src/lib/axios.jsx +0 -19
  217. package/templates/conditional/axios/feature-based/src/lib/axios.ts +0 -19
  218. package/templates/conditional/axios/feature-based/src/lib/index.js +0 -1
  219. package/templates/conditional/axios/feature-based/src/lib/index.ts +0 -1
  220. package/templates/conditional/fetch/component-based/src/services/api.jsx +0 -27
  221. package/templates/conditional/fetch/component-based/src/services/api.ts +0 -27
  222. package/templates/conditional/fetch/component-based/src/services/index.js +0 -1
  223. package/templates/conditional/fetch/component-based/src/services/index.ts +0 -1
  224. package/templates/conditional/fetch/feature-based/src/lib/api.jsx +0 -27
  225. package/templates/conditional/fetch/feature-based/src/lib/api.ts +0 -27
  226. package/templates/conditional/fetch/feature-based/src/lib/index.js +0 -1
  227. package/templates/conditional/fetch/feature-based/src/lib/index.ts +0 -1
  228. package/templates/conditional/router/component-based/src/routes/index.jsx +0 -13
  229. package/templates/conditional/router/component-based/src/routes/index.tsx +0 -13
  230. package/templates/conditional/router/feature-based/src/app/router.jsx +0 -13
  231. package/templates/conditional/router/feature-based/src/app/router.tsx +0 -13
  232. package/templates/conditional/state/redux/feature-based/src/stores/hooks.ts +0 -4
  233. package/templates/css/tailwind/src/index.css +0 -1
  234. /package/templates/architectures/component-based/src/{components/layout → config}/.gitkeep +0 -0
  235. /package/templates/architectures/{feature-based/src/features/home/interfaces → component-based/src/providers}/.gitkeep +0 -0
  236. /package/templates/architectures/{feature-based/src/lib → component-based/src/styles}/.gitkeep +0 -0
  237. /package/templates/architectures/feature-based/src/{stores → features/home/types}/.gitkeep +0 -0
  238. /package/templates/architectures/feature-based/src/{components → shared/components}/ui/index.js +0 -0
  239. /package/templates/architectures/feature-based/src/{components → shared/components}/ui/index.ts +0 -0
  240. /package/templates/architectures/feature-based/src/{hooks → shared/hooks}/useLocalStorage.jsx +0 -0
  241. /package/templates/architectures/feature-based/src/{utils → shared/utils}/cn.jsx +0 -0
  242. /package/templates/conditional/state/redux/feature-based/src/{stores → shared/stores}/hooks.js +0 -0
  243. /package/templates/conditional/state/redux/feature-based/src/{stores → shared/stores}/index.js +0 -0
  244. /package/templates/conditional/testing/vitest/{src → feature-based/src}/__tests__/App.test.jsx +0 -0
  245. /package/templates/conditional/testing/vitest/{src → feature-based/src}/__tests__/App.test.tsx +0 -0
  246. /package/templates/css/bootstrap/src/{index.css → globals.css} +0 -0
  247. /package/templates/{architectures/feature-based/src/styles → css/tailwind/src}/globals.css +0 -0
@@ -0,0 +1,20 @@
1
+ import { useEffect, useState } from "react";
2
+ import { AppContext } from "./appcontext";
3
+
4
+ export function AppProvider({ children }) {
5
+ const [theme, setTheme] = useState(
6
+ () => localStorage.getItem("theme") ?? "light"
7
+ );
8
+
9
+ useEffect(() => {
10
+ localStorage.setItem("theme", theme);
11
+ document.documentElement.dataset.theme =
12
+ theme === "dark" ? "dark" : "light";
13
+ }, [theme]);
14
+
15
+ return (
16
+ <AppContext.Provider value={{ theme, setTheme }}>
17
+ {children}
18
+ </AppContext.Provider>
19
+ );
20
+ }
@@ -0,0 +1,24 @@
1
+ import {
2
+ useEffect,
3
+ useState,
4
+ type ReactNode,
5
+ } from "react";
6
+ import { AppContext } from "./appcontext";
7
+
8
+ export function AppProvider({ children }: { children: ReactNode }) {
9
+ const [theme, setTheme] = useState(
10
+ () => localStorage.getItem("theme") ?? "light"
11
+ );
12
+
13
+ useEffect(() => {
14
+ localStorage.setItem("theme", theme);
15
+ document.documentElement.dataset.theme =
16
+ theme === "dark" ? "dark" : "light";
17
+ }, [theme]);
18
+
19
+ return (
20
+ <AppContext.Provider value={{ theme, setTheme }}>
21
+ {children}
22
+ </AppContext.Provider>
23
+ );
24
+ }
@@ -0,0 +1,3 @@
1
+ import { createContext } from "react";
2
+
3
+ export const AppContext = createContext(null);
@@ -0,0 +1,8 @@
1
+ import { createContext } from "react";
2
+
3
+ export interface AppContextValue {
4
+ theme: string;
5
+ setTheme: (theme: string) => void;
6
+ }
7
+
8
+ export const AppContext = createContext<AppContextValue | null>(null);
@@ -11,3 +11,10 @@
11
11
  * @property {string} message
12
12
  * @property {boolean} success
13
13
  */
14
+
15
+ /**
16
+ * @typedef {Object} CreateUserPayload
17
+ * @property {string} email
18
+ * @property {string} name
19
+ */
20
+ export {};
@@ -9,3 +9,8 @@ export interface ApiResponse<T> {
9
9
  message: string;
10
10
  success: boolean;
11
11
  }
12
+
13
+ export interface CreateUserPayload {
14
+ email: string;
15
+ name: string;
16
+ }
@@ -1,3 +1,5 @@
1
- export function cn(...inputs) {
1
+ type ClassValue = string | false | null | undefined;
2
+
3
+ export function cn(...inputs: ClassValue[]): string {
2
4
  return inputs.filter(Boolean).join(" ");
3
5
  }
@@ -1,7 +1,7 @@
1
1
  import React from "react";
2
2
  import ReactDOM from "react-dom/client";
3
3
  import App from "@/app/App";
4
- import "./styles/globals.css";
4
+ import "./shared/styles/globals.css";
5
5
 
6
6
  ReactDOM.createRoot(document.getElementById("root")).render(
7
7
  <React.StrictMode>
@@ -1,9 +1,9 @@
1
1
  import React from "react";
2
2
  import ReactDOM from "react-dom/client";
3
3
  import App from "@/app/App";
4
- import "./styles/globals.css";
4
+ import "./shared/styles/globals.css";
5
5
 
6
- ReactDOM.createRoot(document.getElementById("root")).render(
6
+ ReactDOM.createRoot(document.getElementById("root")!).render(
7
7
  <React.StrictMode>
8
8
  <App />
9
9
  </React.StrictMode>
@@ -19,19 +19,19 @@ const featureDir = path.join(process.cwd(), "src", "features", formattedName);
19
19
  const subdirectories = [
20
20
  "components",
21
21
  "hooks",
22
- "interfaces",
23
22
  "layouts",
24
23
  "pages",
25
24
  "services",
26
25
  "store",
26
+ "types",
27
27
  ];
28
28
 
29
29
  // 3. Initial files with starter content
30
30
  const initialFiles = {
31
- "interfaces/index.ts": `// Types and contracts for the ${formattedName} module\n`,
32
31
  "services/index.ts": `// Endpoints and async calls for the ${formattedName} module\n`,
33
32
  "store/index.ts": `// State for the ${formattedName} module\n`,
34
33
  "pages/index.ts": `// Page components for the ${formattedName} module\n`,
34
+ "types/index.ts": `// Types exclusive to the ${formattedName} module\n`,
35
35
  };
36
36
 
37
37
  // 4. Create the feature
@@ -1,10 +1,20 @@
1
- import React from "react";
2
- import { HomePage } from "@/features/home/pages/HomePage";
1
+ import { ThemeProvider } from "@/app/providers/ThemeProvider";
2
+ import { HomePage } from "@/features/home";
3
3
 
4
4
  export default function App() {
5
5
  return (
6
- <div className="min-h-screen flex items-center justify-center bg-gray-50">
7
- <HomePage />
8
- </div>
6
+ <ThemeProvider>
7
+ <div
8
+ style={{
9
+ minHeight: "100vh",
10
+ display: "flex",
11
+ alignItems: "center",
12
+ justifyContent: "center",
13
+ backgroundColor: "var(--color-bg)",
14
+ }}
15
+ >
16
+ <HomePage />
17
+ </div>
18
+ </ThemeProvider>
9
19
  );
10
20
  }
@@ -1,10 +1,20 @@
1
- import React from "react";
2
- import { HomePage } from "@/features/home/pages/HomePage";
1
+ import { ThemeProvider } from "@/app/providers/ThemeProvider";
2
+ import { HomePage } from "@/features/home";
3
3
 
4
4
  export default function App() {
5
5
  return (
6
- <div className="min-h-screen flex items-center justify-center bg-gray-50">
7
- <HomePage />
8
- </div>
6
+ <ThemeProvider>
7
+ <div
8
+ style={{
9
+ minHeight: "100vh",
10
+ display: "flex",
11
+ alignItems: "center",
12
+ justifyContent: "center",
13
+ backgroundColor: "var(--color-bg)",
14
+ }}
15
+ >
16
+ <HomePage />
17
+ </div>
18
+ </ThemeProvider>
9
19
  );
10
20
  }
@@ -0,0 +1,3 @@
1
+ import { createContext } from "react";
2
+
3
+ export const ThemeContext = createContext(null);
@@ -0,0 +1,8 @@
1
+ import { createContext } from "react";
2
+
3
+ export interface ThemeContextValue {
4
+ theme: string;
5
+ setTheme: (theme: string) => void;
6
+ }
7
+
8
+ export const ThemeContext = createContext<ThemeContextValue | null>(null);
@@ -0,0 +1,10 @@
1
+ import { useContext } from "react";
2
+ import { ThemeContext } from "../contexts/themecontext";
3
+
4
+ export function useTheme() {
5
+ const ctx = useContext(ThemeContext);
6
+ if (!ctx) {
7
+ throw new Error("useTheme must be used within a ThemeProvider");
8
+ }
9
+ return ctx;
10
+ }
@@ -0,0 +1,10 @@
1
+ import { useContext } from "react";
2
+ import { ThemeContext, type ThemeContextValue } from "../contexts/themecontext";
3
+
4
+ export function useTheme(): ThemeContextValue {
5
+ const ctx = useContext(ThemeContext);
6
+ if (!ctx) {
7
+ throw new Error("useTheme must be used within a ThemeProvider");
8
+ }
9
+ return ctx;
10
+ }
@@ -1,5 +1,20 @@
1
- import React from "react";
1
+ import { useEffect, useState } from "react";
2
+ import { ThemeContext } from "../contexts/themecontext";
2
3
 
3
4
  export function ThemeProvider({ children }) {
4
- return <>{children}</>;
5
+ const [theme, setTheme] = useState(
6
+ () => localStorage.getItem("theme") ?? "light"
7
+ );
8
+
9
+ useEffect(() => {
10
+ localStorage.setItem("theme", theme);
11
+ document.documentElement.dataset.theme =
12
+ theme === "dark" ? "dark" : "light";
13
+ }, [theme]);
14
+
15
+ return (
16
+ <ThemeContext.Provider value={{ theme, setTheme }}>
17
+ {children}
18
+ </ThemeContext.Provider>
19
+ );
5
20
  }
@@ -1,5 +1,22 @@
1
- import React from "react";
1
+ import {
2
+ useEffect,
3
+ useState,
4
+ type ReactNode,
5
+ } from "react";
6
+ import { ThemeContext, type ThemeContextValue } from "../contexts/themecontext";
2
7
 
3
- export function ThemeProvider({ children }) {
4
- return <>{children}</>;
8
+ export function ThemeProvider({ children }: { children: ReactNode }) {
9
+ const [theme, setTheme] = useState(
10
+ () => localStorage.getItem("theme") ?? "light"
11
+ );
12
+
13
+ useEffect(() => {
14
+ localStorage.setItem("theme", theme);
15
+ document.documentElement.dataset.theme =
16
+ theme === "dark" ? "dark" : "light";
17
+ }, [theme]);
18
+
19
+ const value: ThemeContextValue = { theme, setTheme };
20
+
21
+ return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;
5
22
  }
@@ -1,11 +1,24 @@
1
- import React from "react";
2
- import { Button } from "@/components/ui";
1
+ import { Button } from "@/shared/components/ui";
3
2
 
4
3
  export function HomePage() {
5
4
  return (
6
- <div className="text-center">
7
- <h1 className="text-4xl font-bold text-gray-900 mb-4">Welcome to Lumen</h1>
8
- <p className="text-gray-600 mb-8">
5
+ <div style={{ textAlign: "center" }}>
6
+ <h1
7
+ style={{
8
+ fontSize: "2.25rem",
9
+ fontWeight: 700,
10
+ color: "var(--color-fg)",
11
+ marginBottom: "1rem",
12
+ }}
13
+ >
14
+ Welcome to Lumen
15
+ </h1>
16
+ <p
17
+ style={{
18
+ color: "var(--color-muted)",
19
+ marginBottom: "2rem",
20
+ }}
21
+ >
9
22
  Your React + Vite project is ready. Start building!
10
23
  </p>
11
24
  <Button>Get Started</Button>
@@ -1,11 +1,24 @@
1
- import React from "react";
2
- import { Button } from "@/components/ui";
1
+ import { Button } from "@/shared/components/ui";
3
2
 
4
3
  export function HomePage() {
5
4
  return (
6
- <div className="text-center">
7
- <h1 className="text-4xl font-bold text-gray-900 mb-4">Welcome to Lumen</h1>
8
- <p className="text-gray-600 mb-8">
5
+ <div style={{ textAlign: "center" }}>
6
+ <h1
7
+ style={{
8
+ fontSize: "2.25rem",
9
+ fontWeight: 700,
10
+ color: "var(--color-fg)",
11
+ marginBottom: "1rem",
12
+ }}
13
+ >
14
+ Welcome to Lumen
15
+ </h1>
16
+ <p
17
+ style={{
18
+ color: "var(--color-muted)",
19
+ marginBottom: "2rem",
20
+ }}
21
+ >
9
22
  Your React + Vite project is ready. Start building!
10
23
  </p>
11
24
  <Button>Get Started</Button>
@@ -0,0 +1,31 @@
1
+ export function Button({
2
+ variant = "primary",
3
+ children,
4
+ className,
5
+ ...props
6
+ }) {
7
+ const styles = {
8
+ primary: { backgroundColor: "var(--color-primary)", color: "white" },
9
+ secondary: {
10
+ backgroundColor: "var(--color-border)",
11
+ color: "var(--color-fg)",
12
+ },
13
+ };
14
+
15
+ return (
16
+ <button
17
+ style={{
18
+ padding: "8px 16px",
19
+ borderRadius: "8px",
20
+ fontWeight: 500,
21
+ border: "none",
22
+ cursor: "pointer",
23
+ ...styles[variant],
24
+ }}
25
+ className={className}
26
+ {...props}
27
+ >
28
+ {children}
29
+ </button>
30
+ );
31
+ }
@@ -0,0 +1,36 @@
1
+ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
2
+ variant?: "primary" | "secondary";
3
+ children: React.ReactNode;
4
+ }
5
+
6
+ export function Button({
7
+ variant = "primary",
8
+ children,
9
+ className,
10
+ ...props
11
+ }: ButtonProps) {
12
+ const styles = {
13
+ primary: { backgroundColor: "var(--color-primary)", color: "white" },
14
+ secondary: {
15
+ backgroundColor: "var(--color-border)",
16
+ color: "var(--color-fg)",
17
+ },
18
+ };
19
+
20
+ return (
21
+ <button
22
+ style={{
23
+ padding: "8px 16px",
24
+ borderRadius: "8px",
25
+ fontWeight: 500,
26
+ border: "none",
27
+ cursor: "pointer",
28
+ ...styles[variant],
29
+ }}
30
+ className={className}
31
+ {...props}
32
+ >
33
+ {children}
34
+ </button>
35
+ );
36
+ }
@@ -1,17 +1,17 @@
1
1
  import { useState, useCallback } from "react";
2
2
 
3
- export function useLocalStorage(key, initialValue) {
4
- const [storedValue, setStoredValue] = useState(() => {
3
+ export function useLocalStorage<T>(key: string, initialValue: T) {
4
+ const [storedValue, setStoredValue] = useState<T>(() => {
5
5
  try {
6
6
  const item = window.localStorage.getItem(key);
7
- return item ? JSON.parse(item) : initialValue;
7
+ return item ? (JSON.parse(item) as T) : initialValue;
8
8
  } catch {
9
9
  return initialValue;
10
10
  }
11
11
  });
12
12
 
13
13
  const setValue = useCallback(
14
- (value) => {
14
+ (value: T | ((prev: T) => T)) => {
15
15
  try {
16
16
  const valueToStore =
17
17
  value instanceof Function ? value(storedValue) : value;
@@ -24,5 +24,5 @@ export function useLocalStorage(key, initialValue) {
24
24
  [key, storedValue]
25
25
  );
26
26
 
27
- return [storedValue, setValue];
27
+ return [storedValue, setValue] as const;
28
28
  }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @typedef {Object} User
3
+ * @property {string} id
4
+ * @property {string} email
5
+ * @property {string} name
6
+ */
7
+
8
+ /**
9
+ * @typedef {Object} ApiResponse
10
+ * @property {*} data
11
+ * @property {string} message
12
+ * @property {boolean} success
13
+ */
14
+
15
+ /**
16
+ * @typedef {Object} CreateUserPayload
17
+ * @property {string} email
18
+ * @property {string} name
19
+ */
20
+ export {};
@@ -0,0 +1,16 @@
1
+ export interface User {
2
+ id: string;
3
+ email: string;
4
+ name: string;
5
+ }
6
+
7
+ export interface ApiResponse<T> {
8
+ data: T;
9
+ message: string;
10
+ success: boolean;
11
+ }
12
+
13
+ export interface CreateUserPayload {
14
+ email: string;
15
+ name: string;
16
+ }
@@ -0,0 +1,5 @@
1
+ type ClassValue = string | false | null | undefined;
2
+
3
+ export function cn(...inputs: ClassValue[]): string {
4
+ return inputs.filter(Boolean).join(" ");
5
+ }
@@ -0,0 +1,7 @@
1
+ export const axiosConfig = {
2
+ baseURL: import.meta.env.VITE_API_URL || "http://localhost:3000",
3
+ timeout: 10000,
4
+ headers: {
5
+ "Content-Type": "application/json",
6
+ },
7
+ };
@@ -0,0 +1,7 @@
1
+ export const axiosConfig = {
2
+ baseURL: import.meta.env.VITE_API_URL || "http://localhost:3000",
3
+ timeout: 10000,
4
+ headers: {
5
+ "Content-Type": "application/json",
6
+ },
7
+ };
@@ -0,0 +1,24 @@
1
+ import axios from "axios";
2
+ import { axiosConfig } from "@/config/axios.config";
3
+
4
+ const api = axios.create(axiosConfig);
5
+
6
+ api.interceptors.request.use((config) => {
7
+ const token = localStorage.getItem("access_token");
8
+ if (token) {
9
+ config.headers.Authorization = `Bearer ${token}`;
10
+ }
11
+ return config;
12
+ });
13
+
14
+ api.interceptors.response.use(
15
+ (response) => response,
16
+ (error) => {
17
+ if (error.response?.status === 401) {
18
+ localStorage.removeItem("access_token");
19
+ }
20
+ return Promise.reject(error);
21
+ },
22
+ );
23
+
24
+ export default api;
@@ -0,0 +1,24 @@
1
+ import axios from "axios";
2
+ import { axiosConfig } from "@/config/axios.config";
3
+
4
+ const api = axios.create(axiosConfig);
5
+
6
+ api.interceptors.request.use((config) => {
7
+ const token = localStorage.getItem("access_token");
8
+ if (token) {
9
+ config.headers.Authorization = `Bearer ${token}`;
10
+ }
11
+ return config;
12
+ });
13
+
14
+ api.interceptors.response.use(
15
+ (response) => response,
16
+ (error) => {
17
+ if (error.response?.status === 401) {
18
+ localStorage.removeItem("access_token");
19
+ }
20
+ return Promise.reject(error);
21
+ },
22
+ );
23
+
24
+ export default api;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @typedef {import("@/types").ApiResponse} ApiResponse
3
+ * @typedef {import("@/types").CreateUserPayload} CreateUserPayload
4
+ * @typedef {import("@/types").User} User
5
+ */
6
+ import api from "@/services/axios.client";
7
+
8
+ export const userService = {
9
+ async getAll() {
10
+ const { data } = await api.get("/users");
11
+ return data;
12
+ },
13
+
14
+ async getById(id) {
15
+ const { data } = await api.get(`/users/${id}`);
16
+ return data;
17
+ },
18
+
19
+ async create(payload) {
20
+ const { data } = await api.post("/users", payload);
21
+ return data;
22
+ },
23
+
24
+ async update(id, payload) {
25
+ const { data } = await api.put(`/users/${id}`, payload);
26
+ return data;
27
+ },
28
+
29
+ async remove(id) {
30
+ const { data } = await api.delete(`/users/${id}`);
31
+ return data;
32
+ },
33
+ };
@@ -0,0 +1,29 @@
1
+ import api from "@/services/axios.client";
2
+ import type { ApiResponse, CreateUserPayload, User } from "@/types";
3
+
4
+ export const userService = {
5
+ async getAll(): Promise<ApiResponse<User[]>> {
6
+ const { data } = await api.get<ApiResponse<User[]>>("/users");
7
+ return data;
8
+ },
9
+
10
+ async getById(id: string): Promise<ApiResponse<User>> {
11
+ const { data } = await api.get<ApiResponse<User>>(`/users/${id}`);
12
+ return data;
13
+ },
14
+
15
+ async create(payload: CreateUserPayload): Promise<ApiResponse<User>> {
16
+ const { data } = await api.post<ApiResponse<User>>("/users", payload);
17
+ return data;
18
+ },
19
+
20
+ async update(id: string, payload: CreateUserPayload): Promise<ApiResponse<User>> {
21
+ const { data } = await api.put<ApiResponse<User>>(`/users/${id}`, payload);
22
+ return data;
23
+ },
24
+
25
+ async remove(id: string): Promise<ApiResponse<null>> {
26
+ const { data } = await api.delete<ApiResponse<null>>(`/users/${id}`);
27
+ return data;
28
+ },
29
+ };
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @typedef {import("@/shared/types").ApiResponse} ApiResponse
3
+ * @typedef {import("@/shared/types").CreateUserPayload} CreateUserPayload
4
+ * @typedef {import("@/shared/types").User} User
5
+ */
6
+ import { api } from "@/shared/lib/axios";
7
+
8
+ export const userService = {
9
+ async getAll() {
10
+ const { data } = await api.get("/users");
11
+ return data;
12
+ },
13
+
14
+ async getById(id) {
15
+ const { data } = await api.get(`/users/${id}`);
16
+ return data;
17
+ },
18
+
19
+ async create(payload) {
20
+ const { data } = await api.post("/users", payload);
21
+ return data;
22
+ },
23
+
24
+ async update(id, payload) {
25
+ const { data } = await api.put(`/users/${id}`, payload);
26
+ return data;
27
+ },
28
+
29
+ async remove(id) {
30
+ const { data } = await api.delete(`/users/${id}`);
31
+ return data;
32
+ },
33
+ };