create-lumen 1.0.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 (156) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +115 -0
  3. package/bin/cli.js +17 -0
  4. package/package.json +42 -0
  5. package/src/cleanup.js +7 -0
  6. package/src/config-cache.js +27 -0
  7. package/src/configure.js +161 -0
  8. package/src/confirm-empty-folder.js +45 -0
  9. package/src/css.js +59 -0
  10. package/src/dependencies.js +101 -0
  11. package/src/injector.js +276 -0
  12. package/src/main.js +197 -0
  13. package/src/prompts.js +232 -0
  14. package/src/readme.js +178 -0
  15. package/src/scaffold.js +29 -0
  16. package/src/utils/dev-server.js +34 -0
  17. package/src/utils/fs.js +74 -0
  18. package/src/utils/pkg-manager.js +17 -0
  19. package/src/utils/yarn-v1.js +10 -0
  20. package/templates/architectures/component-based/main.jsx +10 -0
  21. package/templates/architectures/component-based/main.tsx +10 -0
  22. package/templates/architectures/component-based/src/App.jsx +11 -0
  23. package/templates/architectures/component-based/src/App.tsx +11 -0
  24. package/templates/architectures/component-based/src/components/common/Button.jsx +30 -0
  25. package/templates/architectures/component-based/src/components/common/Button.tsx +35 -0
  26. package/templates/architectures/component-based/src/components/common/index.js +1 -0
  27. package/templates/architectures/component-based/src/components/common/index.ts +1 -0
  28. package/templates/architectures/component-based/src/components/form/.gitkeep +0 -0
  29. package/templates/architectures/component-based/src/components/layout/.gitkeep +0 -0
  30. package/templates/architectures/component-based/src/config/constants.js +2 -0
  31. package/templates/architectures/component-based/src/config/constants.ts +2 -0
  32. package/templates/architectures/component-based/src/config/routes.js +7 -0
  33. package/templates/architectures/component-based/src/config/routes.ts +7 -0
  34. package/templates/architectures/component-based/src/context/AppContext.jsx +13 -0
  35. package/templates/architectures/component-based/src/context/AppContext.tsx +13 -0
  36. package/templates/architectures/component-based/src/hooks/index.js +1 -0
  37. package/templates/architectures/component-based/src/hooks/index.ts +1 -0
  38. package/templates/architectures/component-based/src/hooks/useLocalStorage.jsx +28 -0
  39. package/templates/architectures/component-based/src/hooks/useLocalStorage.ts +28 -0
  40. package/templates/architectures/component-based/src/layouts/MainLayout.jsx +29 -0
  41. package/templates/architectures/component-based/src/layouts/MainLayout.tsx +33 -0
  42. package/templates/architectures/component-based/src/layouts/index.js +1 -0
  43. package/templates/architectures/component-based/src/layouts/index.ts +1 -0
  44. package/templates/architectures/component-based/src/pages/Home/Home.jsx +16 -0
  45. package/templates/architectures/component-based/src/pages/Home/Home.tsx +16 -0
  46. package/templates/architectures/component-based/src/pages/Home/index.js +1 -0
  47. package/templates/architectures/component-based/src/pages/Home/index.ts +1 -0
  48. package/templates/architectures/component-based/src/routes/index.jsx +11 -0
  49. package/templates/architectures/component-based/src/routes/index.tsx +11 -0
  50. package/templates/architectures/component-based/src/services/.gitkeep +0 -0
  51. package/templates/architectures/component-based/src/store/.gitkeep +0 -0
  52. package/templates/architectures/component-based/src/styles/globals.css +7 -0
  53. package/templates/architectures/component-based/src/utils/cn.jsx +3 -0
  54. package/templates/architectures/component-based/src/utils/cn.ts +3 -0
  55. package/templates/architectures/component-based/src/utils/index.js +1 -0
  56. package/templates/architectures/component-based/src/utils/index.ts +1 -0
  57. package/templates/architectures/feature-based/main.jsx +10 -0
  58. package/templates/architectures/feature-based/main.tsx +10 -0
  59. package/templates/architectures/feature-based/scripts/create-feature.mjs +65 -0
  60. package/templates/architectures/feature-based/src/app/App.jsx +10 -0
  61. package/templates/architectures/feature-based/src/app/App.tsx +10 -0
  62. package/templates/architectures/feature-based/src/app/providers/ThemeProvider.jsx +5 -0
  63. package/templates/architectures/feature-based/src/app/providers/ThemeProvider.tsx +5 -0
  64. package/templates/architectures/feature-based/src/components/ui/Button.jsx +23 -0
  65. package/templates/architectures/feature-based/src/components/ui/Button.tsx +28 -0
  66. package/templates/architectures/feature-based/src/components/ui/index.js +1 -0
  67. package/templates/architectures/feature-based/src/components/ui/index.ts +1 -0
  68. package/templates/architectures/feature-based/src/config/constants.js +2 -0
  69. package/templates/architectures/feature-based/src/config/constants.ts +2 -0
  70. package/templates/architectures/feature-based/src/features/home/components/.gitkeep +0 -0
  71. package/templates/architectures/feature-based/src/features/home/hooks/.gitkeep +0 -0
  72. package/templates/architectures/feature-based/src/features/home/index.js +1 -0
  73. package/templates/architectures/feature-based/src/features/home/index.ts +1 -0
  74. package/templates/architectures/feature-based/src/features/home/interfaces/.gitkeep +0 -0
  75. package/templates/architectures/feature-based/src/features/home/layouts/.gitkeep +0 -0
  76. package/templates/architectures/feature-based/src/features/home/pages/HomePage.jsx +14 -0
  77. package/templates/architectures/feature-based/src/features/home/pages/HomePage.tsx +14 -0
  78. package/templates/architectures/feature-based/src/features/home/services/.gitkeep +0 -0
  79. package/templates/architectures/feature-based/src/features/home/store/.gitkeep +0 -0
  80. package/templates/architectures/feature-based/src/hooks/index.js +1 -0
  81. package/templates/architectures/feature-based/src/hooks/index.ts +1 -0
  82. package/templates/architectures/feature-based/src/hooks/useLocalStorage.jsx +28 -0
  83. package/templates/architectures/feature-based/src/hooks/useLocalStorage.ts +28 -0
  84. package/templates/architectures/feature-based/src/lib/.gitkeep +0 -0
  85. package/templates/architectures/feature-based/src/stores/.gitkeep +0 -0
  86. package/templates/architectures/feature-based/src/styles/globals.css +1 -0
  87. package/templates/architectures/feature-based/src/types/index.js +13 -0
  88. package/templates/architectures/feature-based/src/types/index.ts +11 -0
  89. package/templates/architectures/feature-based/src/utils/cn.jsx +3 -0
  90. package/templates/architectures/feature-based/src/utils/cn.ts +6 -0
  91. package/templates/architectures/feature-based/src/utils/index.js +1 -0
  92. package/templates/architectures/feature-based/src/utils/index.ts +1 -0
  93. package/templates/conditional/axios/component-based/src/services/axios.jsx +19 -0
  94. package/templates/conditional/axios/component-based/src/services/axios.ts +19 -0
  95. package/templates/conditional/axios/component-based/src/services/index.js +1 -0
  96. package/templates/conditional/axios/component-based/src/services/index.ts +1 -0
  97. package/templates/conditional/axios/feature-based/src/lib/axios.jsx +19 -0
  98. package/templates/conditional/axios/feature-based/src/lib/axios.ts +19 -0
  99. package/templates/conditional/axios/feature-based/src/lib/index.js +1 -0
  100. package/templates/conditional/axios/feature-based/src/lib/index.ts +1 -0
  101. package/templates/conditional/icons/huge/component-based/src/pages/Home/Home.jsx +20 -0
  102. package/templates/conditional/icons/huge/component-based/src/pages/Home/Home.tsx +20 -0
  103. package/templates/conditional/icons/huge/feature-based/src/features/home/pages/HomePage.jsx +20 -0
  104. package/templates/conditional/icons/huge/feature-based/src/features/home/pages/HomePage.tsx +20 -0
  105. package/templates/conditional/icons/lucide/component-based/src/pages/Home/Home.jsx +20 -0
  106. package/templates/conditional/icons/lucide/component-based/src/pages/Home/Home.tsx +20 -0
  107. package/templates/conditional/icons/lucide/feature-based/src/features/home/pages/HomePage.jsx +20 -0
  108. package/templates/conditional/icons/lucide/feature-based/src/features/home/pages/HomePage.tsx +20 -0
  109. package/templates/conditional/linting/eslint/eslint.config.js +31 -0
  110. package/templates/conditional/linting/eslint/eslint.config.ts +28 -0
  111. package/templates/conditional/linting/oxlint/oxlintrc.json +9 -0
  112. package/templates/conditional/router/component-based/src/App.jsx +11 -0
  113. package/templates/conditional/router/component-based/src/App.tsx +11 -0
  114. package/templates/conditional/router/component-based/src/routes/index.jsx +13 -0
  115. package/templates/conditional/router/component-based/src/routes/index.tsx +13 -0
  116. package/templates/conditional/router/feature-based/src/app/App.jsx +6 -0
  117. package/templates/conditional/router/feature-based/src/app/App.tsx +6 -0
  118. package/templates/conditional/router/feature-based/src/app/router.jsx +13 -0
  119. package/templates/conditional/router/feature-based/src/app/router.tsx +13 -0
  120. package/templates/conditional/state/redux/component-based/src/context/StoreProvider.jsx +7 -0
  121. package/templates/conditional/state/redux/component-based/src/context/StoreProvider.tsx +7 -0
  122. package/templates/conditional/state/redux/component-based/src/pages/Home/counterSlice.jsx +20 -0
  123. package/templates/conditional/state/redux/component-based/src/pages/Home/counterSlice.ts +20 -0
  124. package/templates/conditional/state/redux/component-based/src/store/hooks.js +4 -0
  125. package/templates/conditional/state/redux/component-based/src/store/hooks.ts +4 -0
  126. package/templates/conditional/state/redux/component-based/src/store/index.js +8 -0
  127. package/templates/conditional/state/redux/component-based/src/store/index.ts +11 -0
  128. package/templates/conditional/state/redux/feature-based/src/app/providers/StoreProvider.jsx +7 -0
  129. package/templates/conditional/state/redux/feature-based/src/app/providers/StoreProvider.tsx +7 -0
  130. package/templates/conditional/state/redux/feature-based/src/features/home/store/counterSlice.jsx +20 -0
  131. package/templates/conditional/state/redux/feature-based/src/features/home/store/counterSlice.ts +20 -0
  132. package/templates/conditional/state/redux/feature-based/src/stores/hooks.js +4 -0
  133. package/templates/conditional/state/redux/feature-based/src/stores/hooks.ts +4 -0
  134. package/templates/conditional/state/redux/feature-based/src/stores/index.js +8 -0
  135. package/templates/conditional/state/redux/feature-based/src/stores/index.ts +11 -0
  136. package/templates/conditional/state/zustand/component-based/src/store/useCounterStore.jsx +9 -0
  137. package/templates/conditional/state/zustand/component-based/src/store/useCounterStore.ts +9 -0
  138. package/templates/conditional/state/zustand/feature-based/src/stores/useCounterStore.jsx +9 -0
  139. package/templates/conditional/state/zustand/feature-based/src/stores/useCounterStore.ts +9 -0
  140. package/templates/conditional/testing/jest/jest.config.js +12 -0
  141. package/templates/conditional/testing/jest/jest.config.ts +13 -0
  142. package/templates/conditional/testing/jest/jest.setup.js +1 -0
  143. package/templates/conditional/testing/jest/jest.setup.ts +1 -0
  144. package/templates/conditional/testing/jest/src/__tests__/App.test.jsx +9 -0
  145. package/templates/conditional/testing/jest/src/__tests__/App.test.tsx +9 -0
  146. package/templates/conditional/testing/vitest/src/__tests__/App.test.jsx +10 -0
  147. package/templates/conditional/testing/vitest/src/__tests__/App.test.tsx +10 -0
  148. package/templates/conditional/testing/vitest/src/test/setup.js +1 -0
  149. package/templates/conditional/testing/vitest/src/test/setup.ts +1 -0
  150. package/templates/conditional/testing/vitest/vitest.config.js +18 -0
  151. package/templates/conditional/testing/vitest/vitest.config.ts +18 -0
  152. package/templates/css/bootstrap/src/index.css +1 -0
  153. package/templates/css/none/src/index.css +18 -0
  154. package/templates/css/tailwind/src/index.css +1 -0
  155. package/templates/css/tailwind/vite.config.js +15 -0
  156. package/templates/css/tailwind/vite.config.ts +15 -0
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { Button } from "@/components/common";
3
+
4
+ export function HomePage() {
5
+ return (
6
+ <div style={{ textAlign: "center" }}>
7
+ <h1 style={{ fontSize: "2.25rem", fontWeight: 700, marginBottom: "1rem" }}>
8
+ Welcome to Lumen
9
+ </h1>
10
+ <p style={{ color: "#6b7280", marginBottom: "2rem" }}>
11
+ Your React + Vite project is ready. Start building!
12
+ </p>
13
+ <Button>Get Started</Button>
14
+ </div>
15
+ );
16
+ }
@@ -0,0 +1,16 @@
1
+ import React from "react";
2
+ import { Button } from "@/components/common";
3
+
4
+ export function HomePage() {
5
+ return (
6
+ <div style={{ textAlign: "center" }}>
7
+ <h1 style={{ fontSize: "2.25rem", fontWeight: 700, marginBottom: "1rem" }}>
8
+ Welcome to Lumen
9
+ </h1>
10
+ <p style={{ color: "#6b7280", marginBottom: "2rem" }}>
11
+ Your React + Vite project is ready. Start building!
12
+ </p>
13
+ <Button>Get Started</Button>
14
+ </div>
15
+ );
16
+ }
@@ -0,0 +1 @@
1
+ export { HomePage } from "./Home";
@@ -0,0 +1 @@
1
+ export { HomePage } from "./Home";
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { Routes, Route } from "react-router-dom";
3
+ import { HomePage } from "@/pages/Home";
4
+
5
+ export function AppRoutes() {
6
+ return (
7
+ <Routes>
8
+ <Route path="/" element={<HomePage />} />
9
+ </Routes>
10
+ );
11
+ }
@@ -0,0 +1,11 @@
1
+ import React from "react";
2
+ import { Routes, Route } from "react-router-dom";
3
+ import { HomePage } from "@/pages/Home";
4
+
5
+ export function AppRoutes() {
6
+ return (
7
+ <Routes>
8
+ <Route path="/" element={<HomePage />} />
9
+ </Routes>
10
+ );
11
+ }
@@ -0,0 +1,7 @@
1
+ body {
2
+ margin: 0;
3
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
4
+ sans-serif;
5
+ -webkit-font-smoothing: antialiased;
6
+ -moz-osx-font-smoothing: grayscale;
7
+ }
@@ -0,0 +1,3 @@
1
+ export function cn(...inputs) {
2
+ return inputs.filter(Boolean).join(" ");
3
+ }
@@ -0,0 +1,3 @@
1
+ export function cn(...inputs) {
2
+ return inputs.filter(Boolean).join(" ");
3
+ }
@@ -0,0 +1 @@
1
+ export { cn } from "./cn";
@@ -0,0 +1 @@
1
+ export { cn } from "./cn";
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import ReactDOM from "react-dom/client";
3
+ import App from "@/app/App";
4
+ import "./styles/globals.css";
5
+
6
+ ReactDOM.createRoot(document.getElementById("root")).render(
7
+ <React.StrictMode>
8
+ <App />
9
+ </React.StrictMode>
10
+ );
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import ReactDOM from "react-dom/client";
3
+ import App from "@/app/App";
4
+ import "./styles/globals.css";
5
+
6
+ ReactDOM.createRoot(document.getElementById("root")).render(
7
+ <React.StrictMode>
8
+ <App />
9
+ </React.StrictMode>
10
+ );
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+
3
+ import fs from "fs";
4
+ import path from "path";
5
+
6
+ // 1. Get feature name from CLI args
7
+ const featureName = process.argv[2];
8
+
9
+ if (!featureName) {
10
+ console.error("\x1b[31mError:\x1b[0m Please specify the feature name.");
11
+ console.log("\x1b[36mExample:\x1b[0m npm run create:feature products");
12
+ process.exit(1);
13
+ }
14
+
15
+ const formattedName = featureName.trim().toLowerCase();
16
+ const featureDir = path.join(process.cwd(), "src", "features", formattedName);
17
+
18
+ // 2. Feature-First subdirectories
19
+ const subdirectories = [
20
+ "components",
21
+ "hooks",
22
+ "interfaces",
23
+ "layouts",
24
+ "pages",
25
+ "services",
26
+ "store",
27
+ ];
28
+
29
+ // 3. Initial files with starter content
30
+ const initialFiles = {
31
+ "interfaces/index.ts": `// Types and contracts for the ${formattedName} module\n`,
32
+ "services/index.ts": `// Endpoints and async calls for the ${formattedName} module\n`,
33
+ "store/index.ts": `// State for the ${formattedName} module\n`,
34
+ "pages/index.ts": `// Page components for the ${formattedName} module\n`,
35
+ };
36
+
37
+ // 4. Create the feature
38
+ try {
39
+ if (fs.existsSync(featureDir)) {
40
+ console.error(
41
+ `\x1b[31mError:\x1b[0m Feature "${formattedName}" already exists in src/features/.`
42
+ );
43
+ process.exit(1);
44
+ }
45
+
46
+ console.log(`\x1b[34mCreating feature:\x1b[0m ${formattedName}...`);
47
+
48
+ // Create main directory and subdirectories
49
+ fs.mkdirSync(featureDir, { recursive: true });
50
+ subdirectories.forEach((subDir) => {
51
+ fs.mkdirSync(path.join(featureDir, subDir), { recursive: true });
52
+ });
53
+
54
+ // Create base files
55
+ for (const [filePath, content] of Object.entries(initialFiles)) {
56
+ fs.writeFileSync(path.join(featureDir, filePath), content, "utf8");
57
+ }
58
+
59
+ console.log(
60
+ `\x1b[32mSuccess!\x1b[0m Feature "${formattedName}" created at src/features/${formattedName}`
61
+ );
62
+ } catch (error) {
63
+ console.error("\x1b[31mUnexpected error:\x1b[0m", error);
64
+ process.exit(1);
65
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { HomePage } from "@/features/home/pages/HomePage";
3
+
4
+ export default function App() {
5
+ return (
6
+ <div className="min-h-screen flex items-center justify-center bg-gray-50">
7
+ <HomePage />
8
+ </div>
9
+ );
10
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ import { HomePage } from "@/features/home/pages/HomePage";
3
+
4
+ export default function App() {
5
+ return (
6
+ <div className="min-h-screen flex items-center justify-center bg-gray-50">
7
+ <HomePage />
8
+ </div>
9
+ );
10
+ }
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+
3
+ export function ThemeProvider({ children }) {
4
+ return <>{children}</>;
5
+ }
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+
3
+ export function ThemeProvider({ children }) {
4
+ return <>{children}</>;
5
+ }
@@ -0,0 +1,23 @@
1
+ import React from "react";
2
+
3
+ export function Button({
4
+ variant = "primary",
5
+ children,
6
+ className,
7
+ ...props
8
+ }) {
9
+ const base = "px-4 py-2 rounded-lg font-medium transition-colors";
10
+ const variants = {
11
+ primary: "bg-blue-600 text-white hover:bg-blue-700",
12
+ secondary: "bg-gray-200 text-gray-800 hover:bg-gray-300",
13
+ };
14
+
15
+ return (
16
+ <button
17
+ className={`${base} ${variants[variant]} ${className ?? ""}`}
18
+ {...props}
19
+ >
20
+ {children}
21
+ </button>
22
+ );
23
+ }
@@ -0,0 +1,28 @@
1
+ import React from "react";
2
+
3
+ interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
4
+ variant?: "primary" | "secondary";
5
+ children: React.ReactNode;
6
+ }
7
+
8
+ export function Button({
9
+ variant = "primary",
10
+ children,
11
+ className,
12
+ ...props
13
+ }: ButtonProps) {
14
+ const base = "px-4 py-2 rounded-lg font-medium transition-colors";
15
+ const variants = {
16
+ primary: "bg-blue-600 text-white hover:bg-blue-700",
17
+ secondary: "bg-gray-200 text-gray-800 hover:bg-gray-300",
18
+ };
19
+
20
+ return (
21
+ <button
22
+ className={`${base} ${variants[variant]} ${className ?? ""}`}
23
+ {...props}
24
+ >
25
+ {children}
26
+ </button>
27
+ );
28
+ }
@@ -0,0 +1 @@
1
+ export { Button } from "./Button";
@@ -0,0 +1 @@
1
+ export { Button } from "./Button";
@@ -0,0 +1,2 @@
1
+ export const APP_NAME = "Lumen";
2
+ export const API_BASE_URL = import.meta.env.VITE_API_URL || "http://localhost:3000";
@@ -0,0 +1,2 @@
1
+ export const APP_NAME = "Lumen";
2
+ export const API_BASE_URL = import.meta.env.VITE_API_URL || "http://localhost:3000";
@@ -0,0 +1 @@
1
+ export { HomePage } from "./pages/HomePage";
@@ -0,0 +1 @@
1
+ export { HomePage } from "./pages/HomePage";
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ import { Button } from "@/components/ui";
3
+
4
+ export function HomePage() {
5
+ 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">
9
+ Your React + Vite project is ready. Start building!
10
+ </p>
11
+ <Button>Get Started</Button>
12
+ </div>
13
+ );
14
+ }
@@ -0,0 +1,14 @@
1
+ import React from "react";
2
+ import { Button } from "@/components/ui";
3
+
4
+ export function HomePage() {
5
+ 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">
9
+ Your React + Vite project is ready. Start building!
10
+ </p>
11
+ <Button>Get Started</Button>
12
+ </div>
13
+ );
14
+ }
@@ -0,0 +1 @@
1
+ export { useLocalStorage } from "./useLocalStorage";
@@ -0,0 +1 @@
1
+ export { useLocalStorage } from "./useLocalStorage";
@@ -0,0 +1,28 @@
1
+ import { useState, useCallback } from "react";
2
+
3
+ export function useLocalStorage(key, initialValue) {
4
+ const [storedValue, setStoredValue] = useState(() => {
5
+ try {
6
+ const item = window.localStorage.getItem(key);
7
+ return item ? JSON.parse(item) : initialValue;
8
+ } catch {
9
+ return initialValue;
10
+ }
11
+ });
12
+
13
+ const setValue = useCallback(
14
+ (value) => {
15
+ try {
16
+ const valueToStore =
17
+ value instanceof Function ? value(storedValue) : value;
18
+ setStoredValue(valueToStore);
19
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
20
+ } catch (error) {
21
+ console.error(error);
22
+ }
23
+ },
24
+ [key, storedValue]
25
+ );
26
+
27
+ return [storedValue, setValue];
28
+ }
@@ -0,0 +1,28 @@
1
+ import { useState, useCallback } from "react";
2
+
3
+ export function useLocalStorage(key, initialValue) {
4
+ const [storedValue, setStoredValue] = useState(() => {
5
+ try {
6
+ const item = window.localStorage.getItem(key);
7
+ return item ? JSON.parse(item) : initialValue;
8
+ } catch {
9
+ return initialValue;
10
+ }
11
+ });
12
+
13
+ const setValue = useCallback(
14
+ (value) => {
15
+ try {
16
+ const valueToStore =
17
+ value instanceof Function ? value(storedValue) : value;
18
+ setStoredValue(valueToStore);
19
+ window.localStorage.setItem(key, JSON.stringify(valueToStore));
20
+ } catch (error) {
21
+ console.error(error);
22
+ }
23
+ },
24
+ [key, storedValue]
25
+ );
26
+
27
+ return [storedValue, setValue];
28
+ }
@@ -0,0 +1 @@
1
+ @import "tailwindcss";
@@ -0,0 +1,13 @@
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
+ */
@@ -0,0 +1,11 @@
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
+ }
@@ -0,0 +1,3 @@
1
+ export function cn(...inputs) {
2
+ return inputs.filter(Boolean).join(" ");
3
+ }
@@ -0,0 +1,6 @@
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+
4
+ export function cn(...inputs) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -0,0 +1 @@
1
+ export { cn } from "./cn";
@@ -0,0 +1 @@
1
+ export { cn } from "./cn";
@@ -0,0 +1,19 @@
1
+ import axios from "axios";
2
+ import { API_BASE_URL } from "@/config/constants";
3
+
4
+ const api = axios.create({
5
+ baseURL: API_BASE_URL,
6
+ headers: {
7
+ "Content-Type": "application/json",
8
+ },
9
+ });
10
+
11
+ api.interceptors.request.use((config) => {
12
+ const token = localStorage.getItem("access_token");
13
+ if (token) {
14
+ config.headers.Authorization = `Bearer ${token}`;
15
+ }
16
+ return config;
17
+ });
18
+
19
+ export default api;
@@ -0,0 +1,19 @@
1
+ import axios from "axios";
2
+ import { API_BASE_URL } from "@/config/constants";
3
+
4
+ const api = axios.create({
5
+ baseURL: API_BASE_URL,
6
+ headers: {
7
+ "Content-Type": "application/json",
8
+ },
9
+ });
10
+
11
+ api.interceptors.request.use((config) => {
12
+ const token = localStorage.getItem("access_token");
13
+ if (token) {
14
+ config.headers.Authorization = `Bearer ${token}`;
15
+ }
16
+ return config;
17
+ });
18
+
19
+ export default api;
@@ -0,0 +1 @@
1
+ export { default as api } from "./axios";
@@ -0,0 +1 @@
1
+ export { default as api } from "./axios";
@@ -0,0 +1,19 @@
1
+ import axios from "axios";
2
+ import { API_BASE_URL } from "@/config/constants";
3
+
4
+ const api = axios.create({
5
+ baseURL: API_BASE_URL,
6
+ headers: {
7
+ "Content-Type": "application/json",
8
+ },
9
+ });
10
+
11
+ api.interceptors.request.use((config) => {
12
+ const token = localStorage.getItem("access_token");
13
+ if (token) {
14
+ config.headers.Authorization = `Bearer ${token}`;
15
+ }
16
+ return config;
17
+ });
18
+
19
+ export default api;
@@ -0,0 +1,19 @@
1
+ import axios from "axios";
2
+ import { API_BASE_URL } from "@/config/constants";
3
+
4
+ const api = axios.create({
5
+ baseURL: API_BASE_URL,
6
+ headers: {
7
+ "Content-Type": "application/json",
8
+ },
9
+ });
10
+
11
+ api.interceptors.request.use((config) => {
12
+ const token = localStorage.getItem("access_token");
13
+ if (token) {
14
+ config.headers.Authorization = `Bearer ${token}`;
15
+ }
16
+ return config;
17
+ });
18
+
19
+ export default api;
@@ -0,0 +1 @@
1
+ export { default as api } from "./axios";
@@ -0,0 +1 @@
1
+ export { default as api } from "./axios";
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { Sun, Moon, Github } from "@hugeicons/react";
3
+ import { Button } from "@/components/common";
4
+
5
+ export function HomePage() {
6
+ return (
7
+ <div className="text-center">
8
+ <div className="flex justify-center gap-4 mb-6">
9
+ <Sun className="w-8 h-8 text-yellow-500" />
10
+ <Moon className="w-8 h-8 text-blue-500" />
11
+ <Github className="w-8 h-8 text-gray-800" />
12
+ </div>
13
+ <h1 className="text-4xl font-bold text-gray-900 mb-4">Welcome to Lumen</h1>
14
+ <p className="text-gray-600 mb-8">
15
+ Your React + Vite project is ready. Start building!
16
+ </p>
17
+ <Button>Get Started</Button>
18
+ </div>
19
+ );
20
+ }
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { Sun, Moon, Github } from "@hugeicons/react";
3
+ import { Button } from "@/components/common";
4
+
5
+ export function HomePage() {
6
+ return (
7
+ <div className="text-center">
8
+ <div className="flex justify-center gap-4 mb-6">
9
+ <Sun className="w-8 h-8 text-yellow-500" />
10
+ <Moon className="w-8 h-8 text-blue-500" />
11
+ <Github className="w-8 h-8 text-gray-800" />
12
+ </div>
13
+ <h1 className="text-4xl font-bold text-gray-900 mb-4">Welcome to Lumen</h1>
14
+ <p className="text-gray-600 mb-8">
15
+ Your React + Vite project is ready. Start building!
16
+ </p>
17
+ <Button>Get Started</Button>
18
+ </div>
19
+ );
20
+ }
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { Sun, Moon, Github } from "@hugeicons/react";
3
+ import { Button } from "@/components/ui";
4
+
5
+ export function HomePage() {
6
+ return (
7
+ <div className="text-center">
8
+ <div className="flex justify-center gap-4 mb-6">
9
+ <Sun className="w-8 h-8 text-yellow-500" />
10
+ <Moon className="w-8 h-8 text-blue-500" />
11
+ <Github className="w-8 h-8 text-gray-800" />
12
+ </div>
13
+ <h1 className="text-4xl font-bold text-gray-900 mb-4">Welcome to Lumen</h1>
14
+ <p className="text-gray-600 mb-8">
15
+ Your React + Vite project is ready. Start building!
16
+ </p>
17
+ <Button>Get Started</Button>
18
+ </div>
19
+ );
20
+ }
@@ -0,0 +1,20 @@
1
+ import React from "react";
2
+ import { Sun, Moon, Github } from "@hugeicons/react";
3
+ import { Button } from "@/components/ui";
4
+
5
+ export function HomePage() {
6
+ return (
7
+ <div className="text-center">
8
+ <div className="flex justify-center gap-4 mb-6">
9
+ <Sun className="w-8 h-8 text-yellow-500" />
10
+ <Moon className="w-8 h-8 text-blue-500" />
11
+ <Github className="w-8 h-8 text-gray-800" />
12
+ </div>
13
+ <h1 className="text-4xl font-bold text-gray-900 mb-4">Welcome to Lumen</h1>
14
+ <p className="text-gray-600 mb-8">
15
+ Your React + Vite project is ready. Start building!
16
+ </p>
17
+ <Button>Get Started</Button>
18
+ </div>
19
+ );
20
+ }