create-reactivite 1.0.2 → 1.0.4

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/README.md ADDED
@@ -0,0 +1,177 @@
1
+ # create-reactivite
2
+
3
+ A modern React boilerplate generator that creates production-ready applications with React, Vite, TypeScript, Tailwind CSS, and shadcn/ui components.
4
+
5
+ ## 🚀 Features
6
+
7
+ - **⚡ Vite** - Lightning fast build tool and dev server
8
+ - **⚛️ React 19** - Latest React with modern features
9
+ - **📘 TypeScript** - Full TypeScript support with strict configuration
10
+ - **🎨 Tailwind CSS v4** - Latest Tailwind with modern CSS features
11
+ - **🧩 shadcn/ui** - Beautiful, accessible UI components
12
+ - **📦 Radix UI** - Unstyled, accessible components
13
+ - **🌙 Dark Mode** - Built-in theme switching with next-themes
14
+ - **📅 Date Picker** - React Day Picker integration
15
+ - **🔔 Toast Notifications** - Sonner for elegant notifications
16
+ - **🎯 ESLint** - Code linting with modern configuration
17
+ - **📱 Responsive** - Mobile-first responsive design
18
+ - **🎭 Icons** - Lucide React icon library
19
+
20
+ ## 📦 Installation
21
+
22
+ ### Using npx (Recommended)
23
+
24
+ ```bash
25
+ npx create-reactivite my-app
26
+ cd my-app
27
+ pnpm dev
28
+ ```
29
+
30
+ ### Using npm
31
+
32
+ ```bash
33
+ npm create reactivite my-app
34
+ cd my-app
35
+ npm run dev
36
+ ```
37
+
38
+ ### Install in current directory
39
+
40
+ ```bash
41
+ npx create-reactivite .
42
+ ```
43
+
44
+ ## 🛠️ What's Included
45
+
46
+ ### Core Technologies
47
+
48
+ - **React 19.1.1** - Latest React with concurrent features
49
+ - **TypeScript 5.9.3** - Strict type checking
50
+ - **Vite 7.1.7** - Fast build tool and dev server
51
+ - **Tailwind CSS 4.1.14** - Utility-first CSS framework
52
+
53
+ ### UI Components
54
+
55
+ The template includes a comprehensive set of pre-built shadcn/ui components:
56
+
57
+ - **Layout**: Card, Separator, Dialog
58
+ - **Forms**: Button, Checkbox, Select, Calendar
59
+ - **Navigation**: Accordion, Collapsible, Toggle
60
+ - **Feedback**: Alert, Badge, Spinner, Toast (Sonner)
61
+ - **Data Display**: Avatar, Table, Tooltip
62
+
63
+ ### Development Tools
64
+
65
+ - **ESLint** - Code linting with React and TypeScript rules
66
+ - **TypeScript** - Strict configuration for better code quality
67
+ - **Path Aliases** - Clean imports with `@/` prefix
68
+ - **Hot Reload** - Instant updates during development
69
+
70
+ ## 🏗️ Project Structure
71
+
72
+ ```
73
+ my-app/
74
+ ├── public/
75
+ │ └── vite.svg
76
+ ├── src/
77
+ │ ├── assets/
78
+ │ ├── components/
79
+ │ │ ├── ui/ # shadcn/ui components
80
+ │ │ └── home-page-components/
81
+ │ ├── lib/
82
+ │ │ └── utils.ts # Utility functions
83
+ │ ├── pages/
84
+ │ │ └── Homepage/
85
+ │ ├── App.tsx
86
+ │ ├── main.tsx
87
+ │ └── global.css
88
+ ├── components.json # shadcn/ui configuration
89
+ ├── package.json
90
+ ├── tsconfig.json
91
+ ├── vite.config.ts
92
+ └── eslint.config.js
93
+ ```
94
+
95
+ ## 🚀 Getting Started
96
+
97
+ 1. **Create your project**:
98
+ ```bash
99
+ npx create-reactivite my-awesome-app
100
+ cd my-awesome-app
101
+ ```
102
+
103
+ 2. **Install dependencies** (automatically done):
104
+ ```bash
105
+ pnpm install # or npm install
106
+ ```
107
+
108
+ 3. **Start development server**:
109
+ ```bash
110
+ pnpm dev # or npm run dev
111
+ ```
112
+
113
+ 4. **Open your browser** and visit `http://localhost:5173`
114
+
115
+ ## 📝 Available Scripts
116
+
117
+ - `pnpm dev` - Start development server
118
+ - `pnpm build` - Build for production
119
+ - `pnpm preview` - Preview production build
120
+ - `pnpm lint` - Run ESLint
121
+
122
+ ## 🎨 Adding Components
123
+
124
+ This template uses shadcn/ui. To add new components:
125
+
126
+ ```bash
127
+ npx shadcn@latest add button
128
+ npx shadcn@latest add input
129
+ npx shadcn@latest add form
130
+ ```
131
+
132
+ ## 🔧 Configuration
133
+
134
+ ### Tailwind CSS
135
+
136
+ The project uses Tailwind CSS v4 with the new Vite plugin. Configuration is handled through CSS variables and the `components.json` file.
137
+
138
+ ### TypeScript
139
+
140
+ Strict TypeScript configuration is included with path aliases:
141
+
142
+ ```typescript
143
+ import { Button } from "@/components/ui/button"
144
+ import { utils } from "@/lib/utils"
145
+ ```
146
+
147
+ ### ESLint
148
+
149
+ Modern ESLint configuration with React and TypeScript support.
150
+
151
+ ## 🌙 Dark Mode
152
+
153
+ Dark mode is pre-configured using `next-themes`. Toggle between light and dark themes seamlessly.
154
+
155
+ ## 📱 Responsive Design
156
+
157
+ All components are built with mobile-first responsive design principles using Tailwind CSS.
158
+
159
+ ## 🤝 Contributing
160
+
161
+ Contributions are welcome! Please feel free to submit a Pull Request.
162
+
163
+ ## 📄 License
164
+
165
+ MIT License - feel free to use this template for your projects.
166
+
167
+ ## 🔗 Links
168
+
169
+ - [React](https://react.dev/)
170
+ - [Vite](https://vite.dev/)
171
+ - [Tailwind CSS](https://tailwindcss.com/)
172
+ - [shadcn/ui](https://ui.shadcn.com/)
173
+ - [TypeScript](https://www.typescriptlang.org/)
174
+
175
+ ---
176
+
177
+ **Happy coding! 🎉**
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "create-reactivite",
3
- "version": "1.0.2",
4
- "description": "React + Vite + Tailwind boilerplate creator",
3
+ "version": "1.0.4",
4
+ "description": "⚡ Effortlessly scaffold modern React + Vite + Tailwind CSS projects with a clean structure and ready-to-use configuration. Create Reactivite helps you instantly start new React apps with best practices, Shadcn/UI support, and zero setup hassle.",
5
5
  "bin": {
6
6
  "create-reactivite": "./index.js"
7
7
  },
@@ -10,9 +10,42 @@
10
10
  "index.js",
11
11
  "template/"
12
12
  ],
13
- "dependencies": {
14
- "prompts": "^2.4.2",
15
- "fs-extra": "^11.2.0",
16
- "execa": "^7.1.0"
17
- }
13
+ "dependencies": {
14
+ "prompts": "^2.4.2",
15
+ "fs-extra": "^11.2.0",
16
+ "execa": "^7.1.0"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://github.com/jsznpm/create-reactivite.git"
21
+ },
22
+ "bugs": {
23
+ "url": "https://github.com/jsznpm/create-reactivite/issues"
24
+ },
25
+ "homepage": "https://github.com/jsznpm/create-reactivite#readme",
26
+ "keywords": [
27
+ "react",
28
+ "vite",
29
+ "tailwind",
30
+ "tailwindcss",
31
+ "shadcn",
32
+ "boilerplate",
33
+ "template",
34
+ "react-template",
35
+ "vite-react-template",
36
+ "create-react-app",
37
+ "react-cli",
38
+ "project-generator",
39
+ "starter-kit",
40
+ "frontend",
41
+ "typescript",
42
+ "reactivite",
43
+ "create-reactivite"
44
+ ],
45
+ "author": {
46
+ "name": "Javid Salimov",
47
+ "email": "",
48
+ "url": "https://github.com/jsznpm"
49
+ },
50
+ "license": "MIT"
18
51
  }
@@ -29,6 +29,8 @@
29
29
  "react": "^19.1.1",
30
30
  "react-day-picker": "^9.11.1",
31
31
  "react-dom": "^19.1.1",
32
+ "react-router": "^7.9.4",
33
+ "recharts": "^3.2.1",
32
34
  "sonner": "^2.0.7",
33
35
  "tailwind-merge": "^3.3.1",
34
36
  "tailwindcss": "^4.1.14"
@@ -65,6 +65,12 @@ importers:
65
65
  react-dom:
66
66
  specifier: ^19.1.1
67
67
  version: 19.2.0(react@19.2.0)
68
+ react-router:
69
+ specifier: ^7.9.4
70
+ version: 7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
71
+ recharts:
72
+ specifier: ^3.2.1
73
+ version: 3.2.1(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react-is@19.2.0)(react@19.2.0)(redux@5.0.1)
68
74
  sonner:
69
75
  specifier: ^2.0.7
70
76
  version: 2.0.7(react-dom@19.2.0(react@19.2.0))(react@19.2.0)
@@ -838,6 +844,17 @@ packages:
838
844
  '@radix-ui/rect@1.1.1':
839
845
  resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
840
846
 
847
+ '@reduxjs/toolkit@2.9.0':
848
+ resolution: {integrity: sha512-fSfQlSRu9Z5yBkvsNhYF2rPS8cGXn/TZVrlwN1948QyZ8xMZ0JvP50S2acZNaf+o63u6aEeMjipFyksjIcWrog==}
849
+ peerDependencies:
850
+ react: ^16.9.0 || ^17.0.0 || ^18 || ^19
851
+ react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
852
+ peerDependenciesMeta:
853
+ react:
854
+ optional: true
855
+ react-redux:
856
+ optional: true
857
+
841
858
  '@rolldown/pluginutils@1.0.0-beta.38':
842
859
  resolution: {integrity: sha512-N/ICGKleNhA5nc9XXQG/kkKHJ7S55u0x0XUJbbkmdCnFuoRkM1Il12q9q0eX19+M7KKUEPw/daUPIRnxhcxAIw==}
843
860
 
@@ -951,6 +968,12 @@ packages:
951
968
  cpu: [x64]
952
969
  os: [win32]
953
970
 
971
+ '@standard-schema/spec@1.0.0':
972
+ resolution: {integrity: sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==}
973
+
974
+ '@standard-schema/utils@0.3.0':
975
+ resolution: {integrity: sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==}
976
+
954
977
  '@tailwindcss/node@4.1.14':
955
978
  resolution: {integrity: sha512-hpz+8vFk3Ic2xssIA3e01R6jkmsAhvkQdXlEbRTk6S10xDAtiQiM3FyvZVGsucefq764euO/b8WUW9ysLdThHw==}
956
979
 
@@ -1053,6 +1076,33 @@ packages:
1053
1076
  '@types/babel__traverse@7.28.0':
1054
1077
  resolution: {integrity: sha512-8PvcXf70gTDZBgt9ptxJ8elBeBjcLOAcOtoO/mPJjtji1+CdGbHgm77om1GrsPxsiE+uXIpNSK64UYaIwQXd4Q==}
1055
1078
 
1079
+ '@types/d3-array@3.2.2':
1080
+ resolution: {integrity: sha512-hOLWVbm7uRza0BYXpIIW5pxfrKe0W+D5lrFiAEYR+pb6w3N2SwSMaJbXdUfSEv+dT4MfHBLtn5js0LAWaO6otw==}
1081
+
1082
+ '@types/d3-color@3.1.3':
1083
+ resolution: {integrity: sha512-iO90scth9WAbmgv7ogoq57O9YpKmFBbmoEoCHDB2xMBY0+/KVrqAaCDyCE16dUspeOvIxFFRI+0sEtqDqy2b4A==}
1084
+
1085
+ '@types/d3-ease@3.0.2':
1086
+ resolution: {integrity: sha512-NcV1JjO5oDzoK26oMzbILE6HW7uVXOHLQvHshBUW4UMdZGfiY6v5BeQwh9a9tCzv+CeefZQHJt5SRgK154RtiA==}
1087
+
1088
+ '@types/d3-interpolate@3.0.4':
1089
+ resolution: {integrity: sha512-mgLPETlrpVV1YRJIglr4Ez47g7Yxjl1lj7YKsiMCb27VJH9W8NVM6Bb9d8kkpG/uAQS5AmbA48q2IAolKKo1MA==}
1090
+
1091
+ '@types/d3-path@3.1.1':
1092
+ resolution: {integrity: sha512-VMZBYyQvbGmWyWVea0EHs/BwLgxc+MKi1zLDCONksozI4YJMcTt8ZEuIR4Sb1MMTE8MMW49v0IwI5+b7RmfWlg==}
1093
+
1094
+ '@types/d3-scale@4.0.9':
1095
+ resolution: {integrity: sha512-dLmtwB8zkAeO/juAMfnV+sItKjlsw2lKdZVVy6LRr0cBmegxSABiLEpGVmSJJ8O08i4+sGR6qQtb6WtuwJdvVw==}
1096
+
1097
+ '@types/d3-shape@3.1.7':
1098
+ resolution: {integrity: sha512-VLvUQ33C+3J+8p+Daf+nYSOsjB4GXp19/S/aGo60m9h1v6XaxjiT82lKVWJCfzhtuZ3yD7i/TPeC/fuKLLOSmg==}
1099
+
1100
+ '@types/d3-time@3.0.4':
1101
+ resolution: {integrity: sha512-yuzZug1nkAAaBlBBikKZTgzCeA+k1uy4ZFwWANOfKw5z5LRhV0gNA7gNkKm7HoK+HRN0wX3EkxGk0fpbWhmB7g==}
1102
+
1103
+ '@types/d3-timer@3.0.2':
1104
+ resolution: {integrity: sha512-Ps3T8E8dZDam6fUyNiMkekK3XUsaUEik+idO9/YjPtfj2qruF8tFBXS7XhtE4iIXBLxhmLjP3SXpLhVf21I9Lw==}
1105
+
1056
1106
  '@types/estree@1.0.8':
1057
1107
  resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==}
1058
1108
 
@@ -1070,6 +1120,9 @@ packages:
1070
1120
  '@types/react@19.2.2':
1071
1121
  resolution: {integrity: sha512-6mDvHUFSjyT2B2yeNx2nUgMxh9LtOWvkhIU3uePn2I2oyNymUAX1NIsdgviM4CH+JSrp2D2hsMvJOkxY+0wNRA==}
1072
1122
 
1123
+ '@types/use-sync-external-store@0.0.6':
1124
+ resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
1125
+
1073
1126
  '@typescript-eslint/eslint-plugin@8.46.1':
1074
1127
  resolution: {integrity: sha512-rUsLh8PXmBjdiPY+Emjz9NX2yHvhS11v0SR6xNJkm5GM1MO9ea/1GoDKlHHZGrOJclL/cZ2i/vRUYVtjRhrHVQ==}
1075
1128
  engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -1216,6 +1269,10 @@ packages:
1216
1269
  convert-source-map@2.0.0:
1217
1270
  resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
1218
1271
 
1272
+ cookie@1.0.2:
1273
+ resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==}
1274
+ engines: {node: '>=18'}
1275
+
1219
1276
  cross-spawn@7.0.6:
1220
1277
  resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==}
1221
1278
  engines: {node: '>= 8'}
@@ -1223,6 +1280,50 @@ packages:
1223
1280
  csstype@3.1.3:
1224
1281
  resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
1225
1282
 
1283
+ d3-array@3.2.4:
1284
+ resolution: {integrity: sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==}
1285
+ engines: {node: '>=12'}
1286
+
1287
+ d3-color@3.1.0:
1288
+ resolution: {integrity: sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==}
1289
+ engines: {node: '>=12'}
1290
+
1291
+ d3-ease@3.0.1:
1292
+ resolution: {integrity: sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==}
1293
+ engines: {node: '>=12'}
1294
+
1295
+ d3-format@3.1.0:
1296
+ resolution: {integrity: sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==}
1297
+ engines: {node: '>=12'}
1298
+
1299
+ d3-interpolate@3.0.1:
1300
+ resolution: {integrity: sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==}
1301
+ engines: {node: '>=12'}
1302
+
1303
+ d3-path@3.1.0:
1304
+ resolution: {integrity: sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==}
1305
+ engines: {node: '>=12'}
1306
+
1307
+ d3-scale@4.0.2:
1308
+ resolution: {integrity: sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==}
1309
+ engines: {node: '>=12'}
1310
+
1311
+ d3-shape@3.2.0:
1312
+ resolution: {integrity: sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==}
1313
+ engines: {node: '>=12'}
1314
+
1315
+ d3-time-format@4.1.0:
1316
+ resolution: {integrity: sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==}
1317
+ engines: {node: '>=12'}
1318
+
1319
+ d3-time@3.1.0:
1320
+ resolution: {integrity: sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==}
1321
+ engines: {node: '>=12'}
1322
+
1323
+ d3-timer@3.0.1:
1324
+ resolution: {integrity: sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==}
1325
+ engines: {node: '>=12'}
1326
+
1226
1327
  date-fns-jalali@4.1.0-0:
1227
1328
  resolution: {integrity: sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==}
1228
1329
 
@@ -1238,6 +1339,9 @@ packages:
1238
1339
  supports-color:
1239
1340
  optional: true
1240
1341
 
1342
+ decimal.js-light@2.5.1:
1343
+ resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==}
1344
+
1241
1345
  deep-is@0.1.4:
1242
1346
  resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==}
1243
1347
 
@@ -1255,6 +1359,9 @@ packages:
1255
1359
  resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==}
1256
1360
  engines: {node: '>=10.13.0'}
1257
1361
 
1362
+ es-toolkit@1.40.0:
1363
+ resolution: {integrity: sha512-8o6w0KFmU0CiIl0/Q/BCEOabF2IJaELM1T2PWj6e8KqzHv1gdx+7JtFnDwOx1kJH/isJ5NwlDG1nCr1HrRF94Q==}
1364
+
1258
1365
  esbuild@0.25.10:
1259
1366
  resolution: {integrity: sha512-9RiGKvCwaqxO2owP61uQ4BgNborAQskMR6QusfWzQqv7AZOg5oGehdY2pRJMTKuwxd1IDBP4rSbI5lHzU7SMsQ==}
1260
1367
  engines: {node: '>=18'}
@@ -1321,6 +1428,9 @@ packages:
1321
1428
  resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==}
1322
1429
  engines: {node: '>=0.10.0'}
1323
1430
 
1431
+ eventemitter3@5.0.1:
1432
+ resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
1433
+
1324
1434
  fast-deep-equal@3.1.3:
1325
1435
  resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
1326
1436
 
@@ -1412,6 +1522,9 @@ packages:
1412
1522
  resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==}
1413
1523
  engines: {node: '>= 4'}
1414
1524
 
1525
+ immer@10.1.3:
1526
+ resolution: {integrity: sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw==}
1527
+
1415
1528
  import-fresh@3.3.1:
1416
1529
  resolution: {integrity: sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==}
1417
1530
  engines: {node: '>=6'}
@@ -1420,6 +1533,10 @@ packages:
1420
1533
  resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==}
1421
1534
  engines: {node: '>=0.8.19'}
1422
1535
 
1536
+ internmap@2.0.3:
1537
+ resolution: {integrity: sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==}
1538
+ engines: {node: '>=12'}
1539
+
1423
1540
  is-extglob@2.1.1:
1424
1541
  resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
1425
1542
  engines: {node: '>=0.10.0'}
@@ -1658,6 +1775,21 @@ packages:
1658
1775
  peerDependencies:
1659
1776
  react: ^19.2.0
1660
1777
 
1778
+ react-is@19.2.0:
1779
+ resolution: {integrity: sha512-x3Ax3kNSMIIkyVYhWPyO09bu0uttcAIoecO/um/rKGQ4EltYWVYtyiGkS/3xMynrbVQdS69Jhlv8FXUEZehlzA==}
1780
+
1781
+ react-redux@9.2.0:
1782
+ resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==}
1783
+ peerDependencies:
1784
+ '@types/react': ^18.2.25 || ^19
1785
+ react: ^18.0 || ^19
1786
+ redux: ^5.0.0
1787
+ peerDependenciesMeta:
1788
+ '@types/react':
1789
+ optional: true
1790
+ redux:
1791
+ optional: true
1792
+
1661
1793
  react-refresh@0.17.0:
1662
1794
  resolution: {integrity: sha512-z6F7K9bV85EfseRCp2bzrpyQ0Gkw1uLoCel9XBVWPg/TjRj94SkJzUTGfOa4bs7iJvBWtQG0Wq7wnI0syw3EBQ==}
1663
1795
  engines: {node: '>=0.10.0'}
@@ -1682,6 +1814,16 @@ packages:
1682
1814
  '@types/react':
1683
1815
  optional: true
1684
1816
 
1817
+ react-router@7.9.4:
1818
+ resolution: {integrity: sha512-SD3G8HKviFHg9xj7dNODUKDFgpG4xqD5nhyd0mYoB5iISepuZAvzSr8ywxgxKJ52yRzf/HWtVHc9AWwoTbljvA==}
1819
+ engines: {node: '>=20.0.0'}
1820
+ peerDependencies:
1821
+ react: '>=18'
1822
+ react-dom: '>=18'
1823
+ peerDependenciesMeta:
1824
+ react-dom:
1825
+ optional: true
1826
+
1685
1827
  react-style-singleton@2.2.3:
1686
1828
  resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
1687
1829
  engines: {node: '>=10'}
@@ -1696,6 +1838,25 @@ packages:
1696
1838
  resolution: {integrity: sha512-tmbWg6W31tQLeB5cdIBOicJDJRR2KzXsV7uSK9iNfLWQ5bIZfxuPEHp7M8wiHyHnn0DD1i7w3Zmin0FtkrwoCQ==}
1697
1839
  engines: {node: '>=0.10.0'}
1698
1840
 
1841
+ recharts@3.2.1:
1842
+ resolution: {integrity: sha512-0JKwHRiFZdmLq/6nmilxEZl3pqb4T+aKkOkOi/ZISRZwfBhVMgInxzlYU9D4KnCH3KINScLy68m/OvMXoYGZUw==}
1843
+ engines: {node: '>=18'}
1844
+ peerDependencies:
1845
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1846
+ react-dom: ^16.0.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1847
+ react-is: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1848
+
1849
+ redux-thunk@3.1.0:
1850
+ resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==}
1851
+ peerDependencies:
1852
+ redux: ^5.0.0
1853
+
1854
+ redux@5.0.1:
1855
+ resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
1856
+
1857
+ reselect@5.1.1:
1858
+ resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
1859
+
1699
1860
  resolve-from@4.0.0:
1700
1861
  resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
1701
1862
  engines: {node: '>=4'}
@@ -1724,6 +1885,9 @@ packages:
1724
1885
  engines: {node: '>=10'}
1725
1886
  hasBin: true
1726
1887
 
1888
+ set-cookie-parser@2.7.1:
1889
+ resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==}
1890
+
1727
1891
  shebang-command@2.0.0:
1728
1892
  resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
1729
1893
  engines: {node: '>=8'}
@@ -1764,6 +1928,9 @@ packages:
1764
1928
  resolution: {integrity: sha512-nlGpxf+hv0v7GkWBK2V9spgactGOp0qvfWRxUMjqHyzrt3SgwE48DIv/FhqPHJYLHpgW1opq3nERbz5Anq7n1g==}
1765
1929
  engines: {node: '>=18'}
1766
1930
 
1931
+ tiny-invariant@1.3.3:
1932
+ resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
1933
+
1767
1934
  tinyglobby@0.2.15:
1768
1935
  resolution: {integrity: sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==}
1769
1936
  engines: {node: '>=12.0.0'}
@@ -1837,6 +2004,9 @@ packages:
1837
2004
  peerDependencies:
1838
2005
  react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
1839
2006
 
2007
+ victory-vendor@37.3.6:
2008
+ resolution: {integrity: sha512-SbPDPdDBYp+5MJHhBCAyI7wKM3d5ivekigc2Dk2s7pgbZ9wIgIBYGVw4zGHBml/qTFbexrofXW6Gu4noGxrOwQ==}
2009
+
1840
2010
  vite@7.1.9:
1841
2011
  resolution: {integrity: sha512-4nVGliEpxmhCL8DslSAUdxlB6+SMrhB0a1v5ijlh1xB1nEPuy1mxaHxysVucLHuWryAxLWg6a5ei+U4TLn/rFg==}
1842
2012
  engines: {node: ^20.19.0 || >=22.12.0}
@@ -2559,6 +2729,18 @@ snapshots:
2559
2729
 
2560
2730
  '@radix-ui/rect@1.1.1': {}
2561
2731
 
2732
+ '@reduxjs/toolkit@2.9.0(react-redux@9.2.0(@types/react@19.2.2)(react@19.2.0)(redux@5.0.1))(react@19.2.0)':
2733
+ dependencies:
2734
+ '@standard-schema/spec': 1.0.0
2735
+ '@standard-schema/utils': 0.3.0
2736
+ immer: 10.1.3
2737
+ redux: 5.0.1
2738
+ redux-thunk: 3.1.0(redux@5.0.1)
2739
+ reselect: 5.1.1
2740
+ optionalDependencies:
2741
+ react: 19.2.0
2742
+ react-redux: 9.2.0(@types/react@19.2.2)(react@19.2.0)(redux@5.0.1)
2743
+
2562
2744
  '@rolldown/pluginutils@1.0.0-beta.38': {}
2563
2745
 
2564
2746
  '@rollup/rollup-android-arm-eabi@4.52.4':
@@ -2627,6 +2809,10 @@ snapshots:
2627
2809
  '@rollup/rollup-win32-x64-msvc@4.52.4':
2628
2810
  optional: true
2629
2811
 
2812
+ '@standard-schema/spec@1.0.0': {}
2813
+
2814
+ '@standard-schema/utils@0.3.0': {}
2815
+
2630
2816
  '@tailwindcss/node@4.1.14':
2631
2817
  dependencies:
2632
2818
  '@jridgewell/remapping': 2.3.5
@@ -2719,6 +2905,30 @@ snapshots:
2719
2905
  dependencies:
2720
2906
  '@babel/types': 7.28.4
2721
2907
 
2908
+ '@types/d3-array@3.2.2': {}
2909
+
2910
+ '@types/d3-color@3.1.3': {}
2911
+
2912
+ '@types/d3-ease@3.0.2': {}
2913
+
2914
+ '@types/d3-interpolate@3.0.4':
2915
+ dependencies:
2916
+ '@types/d3-color': 3.1.3
2917
+
2918
+ '@types/d3-path@3.1.1': {}
2919
+
2920
+ '@types/d3-scale@4.0.9':
2921
+ dependencies:
2922
+ '@types/d3-time': 3.0.4
2923
+
2924
+ '@types/d3-shape@3.1.7':
2925
+ dependencies:
2926
+ '@types/d3-path': 3.1.1
2927
+
2928
+ '@types/d3-time@3.0.4': {}
2929
+
2930
+ '@types/d3-timer@3.0.2': {}
2931
+
2722
2932
  '@types/estree@1.0.8': {}
2723
2933
 
2724
2934
  '@types/json-schema@7.0.15': {}
@@ -2735,6 +2945,8 @@ snapshots:
2735
2945
  dependencies:
2736
2946
  csstype: 3.1.3
2737
2947
 
2948
+ '@types/use-sync-external-store@0.0.6': {}
2949
+
2738
2950
  '@typescript-eslint/eslint-plugin@8.46.1(@typescript-eslint/parser@8.46.1(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3))(eslint@9.37.0(jiti@2.6.1))(typescript@5.9.3)':
2739
2951
  dependencies:
2740
2952
  '@eslint-community/regexpp': 4.12.1
@@ -2915,6 +3127,8 @@ snapshots:
2915
3127
 
2916
3128
  convert-source-map@2.0.0: {}
2917
3129
 
3130
+ cookie@1.0.2: {}
3131
+
2918
3132
  cross-spawn@7.0.6:
2919
3133
  dependencies:
2920
3134
  path-key: 3.1.1
@@ -2923,6 +3137,44 @@ snapshots:
2923
3137
 
2924
3138
  csstype@3.1.3: {}
2925
3139
 
3140
+ d3-array@3.2.4:
3141
+ dependencies:
3142
+ internmap: 2.0.3
3143
+
3144
+ d3-color@3.1.0: {}
3145
+
3146
+ d3-ease@3.0.1: {}
3147
+
3148
+ d3-format@3.1.0: {}
3149
+
3150
+ d3-interpolate@3.0.1:
3151
+ dependencies:
3152
+ d3-color: 3.1.0
3153
+
3154
+ d3-path@3.1.0: {}
3155
+
3156
+ d3-scale@4.0.2:
3157
+ dependencies:
3158
+ d3-array: 3.2.4
3159
+ d3-format: 3.1.0
3160
+ d3-interpolate: 3.0.1
3161
+ d3-time: 3.1.0
3162
+ d3-time-format: 4.1.0
3163
+
3164
+ d3-shape@3.2.0:
3165
+ dependencies:
3166
+ d3-path: 3.1.0
3167
+
3168
+ d3-time-format@4.1.0:
3169
+ dependencies:
3170
+ d3-time: 3.1.0
3171
+
3172
+ d3-time@3.1.0:
3173
+ dependencies:
3174
+ d3-array: 3.2.4
3175
+
3176
+ d3-timer@3.0.1: {}
3177
+
2926
3178
  date-fns-jalali@4.1.0-0: {}
2927
3179
 
2928
3180
  date-fns@4.1.0: {}
@@ -2931,6 +3183,8 @@ snapshots:
2931
3183
  dependencies:
2932
3184
  ms: 2.1.3
2933
3185
 
3186
+ decimal.js-light@2.5.1: {}
3187
+
2934
3188
  deep-is@0.1.4: {}
2935
3189
 
2936
3190
  detect-libc@2.1.2: {}
@@ -2944,6 +3198,8 @@ snapshots:
2944
3198
  graceful-fs: 4.2.11
2945
3199
  tapable: 2.3.0
2946
3200
 
3201
+ es-toolkit@1.40.0: {}
3202
+
2947
3203
  esbuild@0.25.10:
2948
3204
  optionalDependencies:
2949
3205
  '@esbuild/aix-ppc64': 0.25.10
@@ -3054,6 +3310,8 @@ snapshots:
3054
3310
 
3055
3311
  esutils@2.0.3: {}
3056
3312
 
3313
+ eventemitter3@5.0.1: {}
3314
+
3057
3315
  fast-deep-equal@3.1.3: {}
3058
3316
 
3059
3317
  fast-glob@3.3.3:
@@ -3125,6 +3383,8 @@ snapshots:
3125
3383
 
3126
3384
  ignore@7.0.5: {}
3127
3385
 
3386
+ immer@10.1.3: {}
3387
+
3128
3388
  import-fresh@3.3.1:
3129
3389
  dependencies:
3130
3390
  parent-module: 1.0.1
@@ -3132,6 +3392,8 @@ snapshots:
3132
3392
 
3133
3393
  imurmurhash@0.1.4: {}
3134
3394
 
3395
+ internmap@2.0.3: {}
3396
+
3135
3397
  is-extglob@2.1.1: {}
3136
3398
 
3137
3399
  is-glob@4.0.3:
@@ -3321,6 +3583,17 @@ snapshots:
3321
3583
  react: 19.2.0
3322
3584
  scheduler: 0.27.0
3323
3585
 
3586
+ react-is@19.2.0: {}
3587
+
3588
+ react-redux@9.2.0(@types/react@19.2.2)(react@19.2.0)(redux@5.0.1):
3589
+ dependencies:
3590
+ '@types/use-sync-external-store': 0.0.6
3591
+ react: 19.2.0
3592
+ use-sync-external-store: 1.6.0(react@19.2.0)
3593
+ optionalDependencies:
3594
+ '@types/react': 19.2.2
3595
+ redux: 5.0.1
3596
+
3324
3597
  react-refresh@0.17.0: {}
3325
3598
 
3326
3599
  react-remove-scroll-bar@2.3.8(@types/react@19.2.2)(react@19.2.0):
@@ -3342,6 +3615,14 @@ snapshots:
3342
3615
  optionalDependencies:
3343
3616
  '@types/react': 19.2.2
3344
3617
 
3618
+ react-router@7.9.4(react-dom@19.2.0(react@19.2.0))(react@19.2.0):
3619
+ dependencies:
3620
+ cookie: 1.0.2
3621
+ react: 19.2.0
3622
+ set-cookie-parser: 2.7.1
3623
+ optionalDependencies:
3624
+ react-dom: 19.2.0(react@19.2.0)
3625
+
3345
3626
  react-style-singleton@2.2.3(@types/react@19.2.2)(react@19.2.0):
3346
3627
  dependencies:
3347
3628
  get-nonce: 1.0.1
@@ -3352,6 +3633,34 @@ snapshots:
3352
3633
 
3353
3634
  react@19.2.0: {}
3354
3635
 
3636
+ recharts@3.2.1(@types/react@19.2.2)(react-dom@19.2.0(react@19.2.0))(react-is@19.2.0)(react@19.2.0)(redux@5.0.1):
3637
+ dependencies:
3638
+ '@reduxjs/toolkit': 2.9.0(react-redux@9.2.0(@types/react@19.2.2)(react@19.2.0)(redux@5.0.1))(react@19.2.0)
3639
+ clsx: 2.1.1
3640
+ decimal.js-light: 2.5.1
3641
+ es-toolkit: 1.40.0
3642
+ eventemitter3: 5.0.1
3643
+ immer: 10.1.3
3644
+ react: 19.2.0
3645
+ react-dom: 19.2.0(react@19.2.0)
3646
+ react-is: 19.2.0
3647
+ react-redux: 9.2.0(@types/react@19.2.2)(react@19.2.0)(redux@5.0.1)
3648
+ reselect: 5.1.1
3649
+ tiny-invariant: 1.3.3
3650
+ use-sync-external-store: 1.6.0(react@19.2.0)
3651
+ victory-vendor: 37.3.6
3652
+ transitivePeerDependencies:
3653
+ - '@types/react'
3654
+ - redux
3655
+
3656
+ redux-thunk@3.1.0(redux@5.0.1):
3657
+ dependencies:
3658
+ redux: 5.0.1
3659
+
3660
+ redux@5.0.1: {}
3661
+
3662
+ reselect@5.1.1: {}
3663
+
3355
3664
  resolve-from@4.0.0: {}
3356
3665
 
3357
3666
  reusify@1.1.0: {}
@@ -3394,6 +3703,8 @@ snapshots:
3394
3703
 
3395
3704
  semver@7.7.3: {}
3396
3705
 
3706
+ set-cookie-parser@2.7.1: {}
3707
+
3397
3708
  shebang-command@2.0.0:
3398
3709
  dependencies:
3399
3710
  shebang-regex: 3.0.0
@@ -3427,6 +3738,8 @@ snapshots:
3427
3738
  minizlib: 3.1.0
3428
3739
  yallist: 5.0.0
3429
3740
 
3741
+ tiny-invariant@1.3.3: {}
3742
+
3430
3743
  tinyglobby@0.2.15:
3431
3744
  dependencies:
3432
3745
  fdir: 6.5.0(picomatch@4.0.3)
@@ -3492,6 +3805,23 @@ snapshots:
3492
3805
  dependencies:
3493
3806
  react: 19.2.0
3494
3807
 
3808
+ victory-vendor@37.3.6:
3809
+ dependencies:
3810
+ '@types/d3-array': 3.2.2
3811
+ '@types/d3-ease': 3.0.2
3812
+ '@types/d3-interpolate': 3.0.4
3813
+ '@types/d3-scale': 4.0.9
3814
+ '@types/d3-shape': 3.1.7
3815
+ '@types/d3-time': 3.0.4
3816
+ '@types/d3-timer': 3.0.2
3817
+ d3-array: 3.2.4
3818
+ d3-ease: 3.0.1
3819
+ d3-interpolate: 3.0.1
3820
+ d3-scale: 4.0.2
3821
+ d3-shape: 3.2.0
3822
+ d3-time: 3.1.0
3823
+ d3-timer: 3.0.1
3824
+
3495
3825
  vite@7.1.9(@types/node@24.7.2)(jiti@2.6.1)(lightningcss@1.30.1):
3496
3826
  dependencies:
3497
3827
  esbuild: 0.25.10
@@ -1,13 +1,27 @@
1
1
 
2
2
  import './App.css'
3
- import Home from './pages/Homepage/Homepage'
4
3
 
4
+ import { createBrowserRouter } from "react-router";
5
+ import { RouterProvider } from "react-router/dom";
6
+ import Home from './pages/Homepage/Homepage';
7
+ import DashboardPage from './pages/Dashboard/Dashboard';
8
+ const router = createBrowserRouter([
9
+ {
10
+ path: "/",
11
+ element: <Home />,
12
+ },
13
+ {
14
+ path: "/portfolio",
15
+ element: <h1>Portfolio</h1>,
16
+ },
17
+ {
18
+ path: "/dashboard",
19
+ element: <DashboardPage />,
20
+ },
21
+ ]);
5
22
  function App() {
6
- return (
7
- <>
8
- <Home/>
9
- </>
10
- )
23
+ return <RouterProvider router={router} />
24
+
11
25
  }
12
26
 
13
27
  export default App
@@ -0,0 +1,80 @@
1
+
2
+ import {
3
+ Area,
4
+ AreaChart,
5
+ ResponsiveContainer,
6
+ XAxis,
7
+ YAxis,
8
+ Tooltip,
9
+ } from "recharts";
10
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card";
11
+
12
+ const data = [
13
+ { time: "00:00", users: 120 },
14
+ { time: "04:00", users: 80 },
15
+ { time: "08:00", users: 250 },
16
+ { time: "12:00", users: 420 },
17
+ { time: "16:00", users: 380 },
18
+ { time: "20:00", users: 290 },
19
+ { time: "23:59", users: 180 },
20
+ ];
21
+
22
+ export function ActivityChart() {
23
+ return (
24
+ <Card>
25
+ <CardHeader>
26
+ <CardTitle>User Activity</CardTitle>
27
+ <CardDescription>Active users throughout the day</CardDescription>
28
+ </CardHeader>
29
+ <CardContent>
30
+ <ResponsiveContainer width="100%" height={300}>
31
+ <AreaChart data={data}>
32
+ <defs>
33
+ <linearGradient id="colorUsers" x1="0" y1="0" x2="0" y2="1">
34
+ <stop
35
+ offset="5%"
36
+ stopColor="hsl(var(--primary))"
37
+ stopOpacity={0.3}
38
+ />
39
+ <stop
40
+ offset="95%"
41
+ stopColor="hsl(var(--primary))"
42
+ stopOpacity={0}
43
+ />
44
+ </linearGradient>
45
+ </defs>
46
+ <XAxis
47
+ dataKey="time"
48
+ stroke="hsl(var(--muted-foreground))"
49
+ fontSize={12}
50
+ tickLine={false}
51
+ axisLine={false}
52
+ />
53
+ <YAxis
54
+ stroke="hsl(var(--muted-foreground))"
55
+ fontSize={12}
56
+ tickLine={false}
57
+ axisLine={false}
58
+ />
59
+ <Tooltip
60
+ contentStyle={{
61
+ backgroundColor: "hsl(var(--popover))",
62
+ border: "1px solid hsl(var(--border))",
63
+ borderRadius: "8px",
64
+ }}
65
+ labelStyle={{ color: "hsl(var(--popover-foreground))" }}
66
+ />
67
+ <Area
68
+ type="monotone"
69
+ dataKey="users"
70
+ stroke="hsl(var(--primary))"
71
+ fillOpacity={1}
72
+ fill="url(#colorUsers)"
73
+ strokeWidth={2}
74
+ />
75
+ </AreaChart>
76
+ </ResponsiveContainer>
77
+ </CardContent>
78
+ </Card>
79
+ );
80
+ }
@@ -0,0 +1,38 @@
1
+
2
+ import { Search, Bell, Menu } from "lucide-react";
3
+ import { Button } from "../ui/button";
4
+ import { Input } from "../ui/input";
5
+
6
+
7
+ export function DashboardHeader({ onMenuClick }: { onMenuClick: () => void }) {
8
+ return (
9
+ <header className="sticky top-0 z-40 border-b border-border bg-background/95 backdrop-blur supports-[backdrop-filter]:bg-background/60">
10
+ <div className="flex h-16 items-center gap-4 px-6">
11
+ <Button
12
+ variant="ghost"
13
+ size="icon"
14
+ className="lg:hidden"
15
+ onClick={onMenuClick}
16
+ >
17
+ <Menu className="h-5 w-5" />
18
+ </Button>
19
+
20
+ <div className="flex-1 flex items-center gap-4">
21
+ <div className="relative w-full max-w-md">
22
+ <Search className="absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-muted-foreground" />
23
+ <Input
24
+ type="search"
25
+ placeholder="Search..."
26
+ className="pl-9 bg-muted/50 border-0"
27
+ />
28
+ </div>
29
+ </div>
30
+
31
+ <Button variant="ghost" size="icon" className="relative">
32
+ <Bell className="h-5 w-5" />
33
+ <span className="absolute top-1.5 right-1.5 h-2 w-2 rounded-full bg-primary" />
34
+ </Button>
35
+ </div>
36
+ </header>
37
+ );
38
+ }
@@ -0,0 +1,23 @@
1
+ import type React from "react";
2
+
3
+ import { useState } from "react";
4
+ import { DashboardSidebar } from "./dashboard-sidebar";
5
+ import { DashboardHeader } from "./dashboard-header";
6
+
7
+ export function DashboardLayout({ children }: { children: React.ReactNode }) {
8
+ const [sidebarOpen, setSidebarOpen] = useState(true);
9
+
10
+ return (
11
+ <div className="dark min-h-screen bg-background">
12
+ <DashboardSidebar open={sidebarOpen} />
13
+ <div
14
+ className={`transition-all duration-300 ${
15
+ sidebarOpen ? "lg:pl-64" : "lg:pl-0"
16
+ }`}
17
+ >
18
+ <DashboardHeader onMenuClick={() => setSidebarOpen(!sidebarOpen)} />
19
+ <main className="p-6 lg:p-8">{children}</main>
20
+ </div>
21
+ </div>
22
+ );
23
+ }
@@ -0,0 +1,67 @@
1
+
2
+ import { Avatar, AvatarFallback } from "../ui/avatar";
3
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card";
4
+
5
+ const recentSales = [
6
+ {
7
+ name: "Olivia Martin",
8
+ email: "olivia.martin@email.com",
9
+ amount: "+$1,999.00",
10
+ initials: "OM",
11
+ },
12
+ {
13
+ name: "Jackson Lee",
14
+ email: "jackson.lee@email.com",
15
+ amount: "+$39.00",
16
+ initials: "JL",
17
+ },
18
+ {
19
+ name: "Isabella Nguyen",
20
+ email: "isabella.nguyen@email.com",
21
+ amount: "+$299.00",
22
+ initials: "IN",
23
+ },
24
+ {
25
+ name: "William Kim",
26
+ email: "will@email.com",
27
+ amount: "+$99.00",
28
+ initials: "WK",
29
+ },
30
+ {
31
+ name: "Sofia Davis",
32
+ email: "sofia.davis@email.com",
33
+ amount: "+$39.00",
34
+ initials: "SD",
35
+ },
36
+ ];
37
+
38
+ export function RecentSales() {
39
+ return (
40
+ <Card className="col-span-3">
41
+ <CardHeader>
42
+ <CardTitle>Recent Sales</CardTitle>
43
+ <CardDescription>You made 265 sales this month</CardDescription>
44
+ </CardHeader>
45
+ <CardContent>
46
+ <div className="space-y-6">
47
+ {recentSales.map((sale) => (
48
+ <div key={sale.email} className="flex items-center gap-4">
49
+ <Avatar className="h-10 w-10">
50
+ <AvatarFallback className="bg-primary/10 text-primary font-medium">
51
+ {sale.initials}
52
+ </AvatarFallback>
53
+ </Avatar>
54
+ <div className="flex-1 min-w-0">
55
+ <p className="text-sm font-medium leading-none">{sale.name}</p>
56
+ <p className="text-sm text-muted-foreground mt-1">
57
+ {sale.email}
58
+ </p>
59
+ </div>
60
+ <div className="font-medium">{sale.amount}</div>
61
+ </div>
62
+ ))}
63
+ </div>
64
+ </CardContent>
65
+ </Card>
66
+ );
67
+ }
@@ -0,0 +1,81 @@
1
+ import {
2
+ LayoutDashboard,
3
+ Users,
4
+ ShoppingCart,
5
+ BarChart3,
6
+ Settings,
7
+ FileText,
8
+ Package,
9
+ CreditCard,
10
+ } from "lucide-react";
11
+ import { cn } from "../../lib/utils";
12
+
13
+
14
+ const navigation = [
15
+ { name: "Dashboard", icon: LayoutDashboard, href: "#", current: true },
16
+ { name: "Customers", icon: Users, href: "#", current: false },
17
+ { name: "Products", icon: Package, href: "#", current: false },
18
+ { name: "Orders", icon: ShoppingCart, href: "#", current: false },
19
+ { name: "Analytics", icon: BarChart3, href: "#", current: false },
20
+ { name: "Transactions", icon: CreditCard, href: "#", current: false },
21
+ { name: "Reports", icon: FileText, href: "#", current: false },
22
+ { name: "Settings", icon: Settings, href: "#", current: false },
23
+ ];
24
+
25
+ export function DashboardSidebar({ open }: { open: boolean }) {
26
+ return (
27
+ <>
28
+ <div
29
+ className={cn(
30
+ "fixed inset-y-0 left-0 z-50 w-64 bg-sidebar border-r border-sidebar-border transition-transform duration-300 lg:translate-x-0",
31
+ open ? "translate-x-0" : "-translate-x-full"
32
+ )}
33
+ >
34
+ <div className="flex h-full flex-col">
35
+ <div className="flex h-16 items-center gap-2 border-b border-sidebar-border px-6">
36
+ <div className="flex h-8 w-8 items-center justify-center rounded-lg bg-primary">
37
+ <LayoutDashboard className="h-5 w-5 text-primary-foreground" />
38
+ </div>
39
+ <span className="text-lg font-semibold text-sidebar-foreground">
40
+ Admin Panel
41
+ </span>
42
+ </div>
43
+
44
+ <nav className="flex-1 space-y-1 px-3 py-4">
45
+ {navigation.map((item) => (
46
+ <a
47
+ key={item.name}
48
+ href={item.href}
49
+ className={cn(
50
+ "flex items-center gap-3 rounded-lg px-3 py-2.5 text-sm font-medium transition-colors",
51
+ item.current
52
+ ? "bg-sidebar-accent text-sidebar-accent-foreground"
53
+ : "text-sidebar-foreground/70 hover:bg-sidebar-accent hover:text-sidebar-accent-foreground"
54
+ )}
55
+ >
56
+ <item.icon className="h-5 w-5" />
57
+ {item.name}
58
+ </a>
59
+ ))}
60
+ </nav>
61
+
62
+ <div className="border-t border-sidebar-border p-4">
63
+ <div className="flex items-center gap-3">
64
+ <div className="h-10 w-10 rounded-full bg-primary/20 flex items-center justify-center">
65
+ <span className="text-sm font-semibold text-primary">JD</span>
66
+ </div>
67
+ <div className="flex-1 min-w-0">
68
+ <p className="text-sm font-medium text-sidebar-foreground truncate">
69
+ John Doe
70
+ </p>
71
+ <p className="text-xs text-sidebar-foreground/60 truncate">
72
+ john@example.com
73
+ </p>
74
+ </div>
75
+ </div>
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </>
80
+ );
81
+ }
@@ -0,0 +1,69 @@
1
+
2
+ import {
3
+ Bar,
4
+ BarChart,
5
+ ResponsiveContainer,
6
+ XAxis,
7
+ YAxis,
8
+ Tooltip,
9
+ } from "recharts";
10
+ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card";
11
+
12
+ const data = [
13
+ { name: "Jan", total: 4500 },
14
+ { name: "Feb", total: 3800 },
15
+ { name: "Mar", total: 5200 },
16
+ { name: "Apr", total: 4700 },
17
+ { name: "May", total: 6100 },
18
+ { name: "Jun", total: 5800 },
19
+ { name: "Jul", total: 7200 },
20
+ { name: "Aug", total: 6800 },
21
+ { name: "Sep", total: 7500 },
22
+ { name: "Oct", total: 8200 },
23
+ { name: "Nov", total: 7800 },
24
+ { name: "Dec", total: 9100 },
25
+ ];
26
+
27
+ export function RevenueChart() {
28
+ return (
29
+ <Card className="col-span-4">
30
+ <CardHeader>
31
+ <CardTitle>Revenue Overview</CardTitle>
32
+ <CardDescription>Monthly revenue for the current year</CardDescription>
33
+ </CardHeader>
34
+ <CardContent className="pl-2">
35
+ <ResponsiveContainer width="100%" height={350}>
36
+ <BarChart data={data}>
37
+ <XAxis
38
+ dataKey="name"
39
+ stroke="hsl(var(--muted-foreground))"
40
+ fontSize={12}
41
+ tickLine={false}
42
+ axisLine={false}
43
+ />
44
+ <YAxis
45
+ stroke="hsl(var(--muted-foreground))"
46
+ fontSize={12}
47
+ tickLine={false}
48
+ axisLine={false}
49
+ tickFormatter={(value) => `$${value}`}
50
+ />
51
+ <Tooltip
52
+ contentStyle={{
53
+ backgroundColor: "hsl(var(--popover))",
54
+ border: "1px solid hsl(var(--border))",
55
+ borderRadius: "8px",
56
+ }}
57
+ labelStyle={{ color: "hsl(var(--popover-foreground))" }}
58
+ />
59
+ <Bar
60
+ dataKey="total"
61
+ fill="hsl(var(--primary))"
62
+ radius={[8, 8, 0, 0]}
63
+ />
64
+ </BarChart>
65
+ </ResponsiveContainer>
66
+ </CardContent>
67
+ </Card>
68
+ );
69
+ }
@@ -0,0 +1,50 @@
1
+ import { DollarSign, Users, CreditCard, Activity } from "lucide-react";
2
+ import { Card, CardContent, CardHeader, CardTitle } from "../ui/card";
3
+
4
+ const stats = [
5
+ {
6
+ title: "Total Revenue",
7
+ value: "$45,231.89",
8
+ change: "+20.1% from last month",
9
+ icon: DollarSign,
10
+ },
11
+ {
12
+ title: "Active Users",
13
+ value: "+2,350",
14
+ change: "+180.1% from last month",
15
+ icon: Users,
16
+ },
17
+ {
18
+ title: "Sales",
19
+ value: "+12,234",
20
+ change: "+19% from last month",
21
+ icon: CreditCard,
22
+ },
23
+ {
24
+ title: "Active Now",
25
+ value: "+573",
26
+ change: "+201 since last hour",
27
+ icon: Activity,
28
+ },
29
+ ];
30
+
31
+ export function StatsCards() {
32
+ return (
33
+ <div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
34
+ {stats.map((stat) => (
35
+ <Card key={stat.title}>
36
+ <CardHeader className="flex flex-row items-center justify-between pb-2">
37
+ <CardTitle className="text-sm font-medium text-muted-foreground">
38
+ {stat.title}
39
+ </CardTitle>
40
+ <stat.icon className="h-4 w-4 text-muted-foreground" />
41
+ </CardHeader>
42
+ <CardContent>
43
+ <div className="text-2xl font-bold">{stat.value}</div>
44
+ <p className="text-xs text-muted-foreground mt-1">{stat.change}</p>
45
+ </CardContent>
46
+ </Card>
47
+ ))}
48
+ </div>
49
+ );
50
+ }
@@ -0,0 +1,21 @@
1
+ import * as React from "react"
2
+
3
+ import { cn } from "@/lib/utils"
4
+
5
+ function Input({ className, type, ...props }: React.ComponentProps<"input">) {
6
+ return (
7
+ <input
8
+ type={type}
9
+ data-slot="input"
10
+ className={cn(
11
+ "file:text-foreground placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 border-input h-9 w-full min-w-0 rounded-md border bg-transparent px-3 py-1 text-base shadow-xs transition-[color,box-shadow] outline-none file:inline-flex file:h-7 file:border-0 file:bg-transparent file:text-sm file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
12
+ "focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px]",
13
+ "aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
14
+ className
15
+ )}
16
+ {...props}
17
+ />
18
+ )
19
+ }
20
+
21
+ export { Input }
@@ -0,0 +1,32 @@
1
+ import { ActivityChart } from "../../components/admin-page-components/activity-chart";
2
+ import { DashboardLayout } from "../../components/admin-page-components/dashboard-layout";
3
+ import { RecentSales } from "../../components/admin-page-components/dashboard-sales";
4
+ import { RevenueChart } from "../../components/admin-page-components/revenu-chart";
5
+ import { StatsCards } from "../../components/admin-page-components/stat-cards";
6
+
7
+
8
+ export default function DashboardPage() {
9
+ return (
10
+ <DashboardLayout>
11
+ <div className="flex flex-col gap-6">
12
+ <div>
13
+ <h1 className="text-3xl font-bold tracking-tight text-balance">
14
+ Dashboard
15
+ </h1>
16
+ <p className="text-muted-foreground mt-2">
17
+ Welcome back! Here's an overview of your business metrics.
18
+ </p>
19
+ </div>
20
+
21
+ <StatsCards />
22
+
23
+ <div className="grid gap-6 md:grid-cols-2 lg:grid-cols-7">
24
+ <RevenueChart />
25
+ <RecentSales />
26
+ </div>
27
+
28
+ <ActivityChart />
29
+ </div>
30
+ </DashboardLayout>
31
+ );
32
+ }
@@ -1,14 +1,14 @@
1
- {
2
- "files": [],
3
- "references": [
4
- { "path": "./tsconfig.app.json" },
5
- { "path": "./tsconfig.node.json" }
6
- ],
7
- "compilerOptions": {
8
- "baseUrl": ".",
9
- "paths": {
10
- "@/*": ["./src/*"]
11
- },
12
-
13
- }
14
- }
1
+ {
2
+ "files": [],
3
+ "references": [
4
+ { "path": "./tsconfig.app.json" },
5
+ { "path": "./tsconfig.node.json" }
6
+ ],
7
+ "compilerOptions": {
8
+ "baseUrl": ".",
9
+ "paths": {
10
+ "@/*": ["src/*"]
11
+ }
12
+
13
+ }
14
+ }
@@ -1,14 +1,13 @@
1
- import path from "path";
2
- import tailwindcss from "@tailwindcss/vite";
3
- import react from "@vitejs/plugin-react";
4
- import { defineConfig } from "vite";
5
-
6
- // https://vite.dev/config/
7
- export default defineConfig({
8
- plugins: [react(), tailwindcss()],
9
- resolve: {
10
- alias: {
11
- "@": path.resolve(__dirname, "./src"),
12
- },
13
- },
14
- });
1
+ import { defineConfig } from "vite";
2
+ import react from "@vitejs/plugin-react";
3
+ import tailwindcss from "@tailwindcss/vite";
4
+ import * as path from "path";
5
+
6
+ export default defineConfig({
7
+ plugins: [react(), tailwindcss()],
8
+ resolve: {
9
+ alias: {
10
+ "@": path.resolve(__dirname, "src"),
11
+ },
12
+ },
13
+ });