create-parachute 1.0.2

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 (49) hide show
  1. package/README.md +27 -0
  2. package/bin/index.js +474 -0
  3. package/package.json +29 -0
  4. package/templates/mysql/client/index.html +12 -0
  5. package/templates/mysql/client/package.json +18 -0
  6. package/templates/mysql/client/src/App.jsx +5 -0
  7. package/templates/mysql/client/src/api/client.js +6 -0
  8. package/templates/mysql/client/src/components/Navbar.jsx +57 -0
  9. package/templates/mysql/client/src/components/ProtectedRoute.jsx +10 -0
  10. package/templates/mysql/client/src/layouts/DashboardLayout.jsx +21 -0
  11. package/templates/mysql/client/src/main.jsx +9 -0
  12. package/templates/mysql/client/src/pages/Dashboard.jsx +38 -0
  13. package/templates/mysql/client/src/pages/Login.jsx +138 -0
  14. package/templates/mysql/client/src/pages/Page1.jsx +38 -0
  15. package/templates/mysql/client/src/pages/Page2.jsx +38 -0
  16. package/templates/mysql/client/src/pages/Page3.jsx +38 -0
  17. package/templates/mysql/client/src/router/index.jsx +43 -0
  18. package/templates/mysql/client/src/utils/auth.js +16 -0
  19. package/templates/mysql/client/vite.config.js +6 -0
  20. package/templates/mysql/server/config/db.js +13 -0
  21. package/templates/mysql/server/controllers/authController.js +66 -0
  22. package/templates/mysql/server/index.js +39 -0
  23. package/templates/mysql/server/middleware/authMiddleware.js +7 -0
  24. package/templates/mysql/server/package.json +18 -0
  25. package/templates/mysql/server/routes/authRoutes.js +14 -0
  26. package/templates/sequelize/client/index.html +12 -0
  27. package/templates/sequelize/client/package.json +18 -0
  28. package/templates/sequelize/client/src/App.jsx +5 -0
  29. package/templates/sequelize/client/src/api/client.js +6 -0
  30. package/templates/sequelize/client/src/components/Navbar.jsx +57 -0
  31. package/templates/sequelize/client/src/components/ProtectedRoute.jsx +10 -0
  32. package/templates/sequelize/client/src/layouts/DashboardLayout.jsx +21 -0
  33. package/templates/sequelize/client/src/main.jsx +9 -0
  34. package/templates/sequelize/client/src/pages/Dashboard.jsx +38 -0
  35. package/templates/sequelize/client/src/pages/Login.jsx +138 -0
  36. package/templates/sequelize/client/src/pages/Page1.jsx +38 -0
  37. package/templates/sequelize/client/src/pages/Page2.jsx +38 -0
  38. package/templates/sequelize/client/src/pages/Page3.jsx +38 -0
  39. package/templates/sequelize/client/src/router/index.jsx +43 -0
  40. package/templates/sequelize/client/src/utils/auth.js +16 -0
  41. package/templates/sequelize/client/vite.config.js +6 -0
  42. package/templates/sequelize/server/config/db.js +13 -0
  43. package/templates/sequelize/server/config/sequelize.js +17 -0
  44. package/templates/sequelize/server/controllers/authController.js +62 -0
  45. package/templates/sequelize/server/index.js +42 -0
  46. package/templates/sequelize/server/middleware/authMiddleware.js +7 -0
  47. package/templates/sequelize/server/models/User.js +24 -0
  48. package/templates/sequelize/server/package.json +19 -0
  49. package/templates/sequelize/server/routes/authRoutes.js +14 -0
package/README.md ADDED
@@ -0,0 +1,27 @@
1
+
2
+ # Create Parachute
3
+
4
+ A clean fullstack starter generator for students.
5
+
6
+ ## Usage
7
+
8
+ ```bash
9
+ npx create-parachute my-project
10
+ ```
11
+
12
+ The generator creates:
13
+
14
+ - Express backend
15
+ - React + Vite frontend
16
+ - Raw MySQL or Sequelize option
17
+ - Session authentication
18
+ - Username login
19
+ - Hashed passwords
20
+ - React Router navigation
21
+ - Protected routes
22
+ - Dashboard + 3 pages
23
+ - `schema.sql`
24
+ - `instructions.md`
25
+ - `tailwind.md`
26
+ - `sql.md`
27
+ - Optional dependency installation
package/bin/index.js ADDED
@@ -0,0 +1,474 @@
1
+ #!/usr/bin/env node
2
+ import fs from "fs-extra";
3
+ import path from "path";
4
+ import inquirer from "inquirer";
5
+ import chalk from "chalk";
6
+ import { spawnSync } from "child_process";
7
+ import { fileURLToPath } from "url";
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = path.dirname(__filename);
11
+
12
+ let projectName = process.argv[2];
13
+
14
+ if (!projectName) {
15
+ const projectAnswer = await inquirer.prompt([
16
+ {
17
+ type: "input",
18
+ name: "projectName",
19
+ message: "Project name:",
20
+ validate: (input) => {
21
+ if (!input.trim()) {
22
+ return "Project name is required.";
23
+ }
24
+
25
+ if (!/^[a-zA-Z0-9-_]+$/.test(input)) {
26
+ return "Only letters, numbers, hyphens, and underscores are allowed.";
27
+ }
28
+
29
+ return true;
30
+ },
31
+ filter: (input) => input.trim()
32
+ }
33
+ ]);
34
+
35
+ projectName = projectAnswer.projectName;
36
+ }
37
+
38
+ const answers = await inquirer.prompt([
39
+ {
40
+ type: "input",
41
+ name: "dbName",
42
+ message: "Database name:",
43
+ default: `${projectName.replace(/-/g, "_")}_db`
44
+ },
45
+ {
46
+ type: "input",
47
+ name: "serverPort",
48
+ message: "Backend port:",
49
+ default: "5000"
50
+ },
51
+ {
52
+ type: "input",
53
+ name: "clientPort",
54
+ message: "Frontend port:",
55
+ default: "5173"
56
+ },
57
+ {
58
+ type: "list",
59
+ name: "database",
60
+ message: "Choose database style:",
61
+ choices: [
62
+ { name: "Raw MySQL", value: "mysql" },
63
+ { name: "Sequelize", value: "sequelize" }
64
+ ]
65
+ },
66
+ {
67
+ type: "list",
68
+ name: "theme",
69
+ message: "Choose theme:",
70
+ choices: [
71
+ { name: chalk.blue("Blue"), value: "#2563EB" },
72
+ { name: chalk.green("Green"), value: "#16A34A" },
73
+ { name: chalk.red("Red"), value: "#DC2626" },
74
+ { name: chalk.magenta("Purple"), value: "#9333EA" },
75
+ { name: chalk.yellow("Yellow"), value: "#CA8A04" },
76
+ { name: chalk.cyan("Cyan"), value: "#0891B2" },
77
+ { name: chalk.hex("#800000")("Maroon"), value: "#800000" }
78
+ ]
79
+ },
80
+ {
81
+ type: "confirm",
82
+ name: "installDeps",
83
+ message: "Install backend and frontend dependencies now?",
84
+ default: true
85
+ }
86
+ ]);
87
+
88
+ const template = path.join(__dirname, "..", "templates", answers.database);
89
+ const target = path.join(process.cwd(), projectName);
90
+
91
+ if (fs.existsSync(target)) {
92
+ console.log(chalk.red("Folder already exists. Choose another project name."));
93
+ process.exit(1);
94
+ }
95
+
96
+ await fs.copy(template, target);
97
+
98
+ const env = `PORT=${answers.serverPort}
99
+ DB_HOST=localhost
100
+ DB_USER=root
101
+ DB_PASSWORD=
102
+ DB_NAME=${answers.dbName}
103
+ CLIENT_URL=http://localhost:${answers.clientPort}
104
+ SESSION_SECRET=parachute_secret`;
105
+
106
+ await fs.writeFile(path.join(target, "server/.env"), env);
107
+
108
+ const schema = `CREATE DATABASE IF NOT EXISTS ${answers.dbName};
109
+ USE ${answers.dbName};
110
+
111
+ CREATE TABLE Users(
112
+ UserID INT AUTO_INCREMENT PRIMARY KEY,
113
+ Username VARCHAR(255) UNIQUE NOT NULL,
114
+ Password VARCHAR(255) NOT NULL
115
+ );`;
116
+
117
+ await fs.writeFile(path.join(target, "schema.sql"), schema);
118
+
119
+ const instructions = `# ${projectName}
120
+
121
+ ## 1. Run the database file
122
+
123
+ Open MySQL and run schema.sql.
124
+
125
+ Example:
126
+
127
+ SOURCE /full/path/to/${projectName}/schema.sql;
128
+
129
+ ## 2. Start backend
130
+
131
+ cd server
132
+ npm run dev
133
+
134
+ ## 3. Start frontend
135
+
136
+ cd client
137
+ npm run dev
138
+
139
+ ## Notes
140
+
141
+ - Backend runs on port ${answers.serverPort}
142
+ - Frontend runs on port ${answers.clientPort}
143
+ - Auth uses Username and hashed Password
144
+ - Add your own backend features inside controllers and routes
145
+ - Add your own frontend screens inside client/src/pages
146
+ `;
147
+
148
+ await fs.writeFile(path.join(target, "instructions.md"), instructions);
149
+
150
+ const tailwindCheat = `# Tailwind Cheat Sheet
151
+
152
+ This project uses simple CSS for maximum beginner-friendliness, but this file helps you style fast if you add Tailwind later.
153
+
154
+ ## Layout
155
+
156
+ flex
157
+ grid
158
+ block
159
+ hidden
160
+ relative
161
+ absolute
162
+ fixed
163
+ sticky
164
+
165
+ ## Flexbox
166
+
167
+ flex
168
+ flex-col
169
+ flex-row
170
+ items-center
171
+ items-start
172
+ items-end
173
+ justify-center
174
+ justify-between
175
+ justify-end
176
+ gap-2
177
+ gap-4
178
+ gap-6
179
+
180
+ ## Grid
181
+
182
+ grid
183
+ grid-cols-1
184
+ grid-cols-2
185
+ grid-cols-3
186
+ md:grid-cols-2
187
+ lg:grid-cols-3
188
+
189
+ ## Spacing
190
+
191
+ p-2
192
+ p-4
193
+ p-6
194
+ p-8
195
+ px-4
196
+ px-6
197
+ py-2
198
+ py-3
199
+ py-4
200
+ m-2
201
+ m-4
202
+ mt-4
203
+ mb-4
204
+ mx-auto
205
+
206
+ ## Width and Height
207
+
208
+ w-full
209
+ w-screen
210
+ max-w-md
211
+ max-w-xl
212
+ max-w-6xl
213
+ min-h-screen
214
+ h-screen
215
+
216
+ ## Typography
217
+
218
+ text-sm
219
+ text-base
220
+ text-lg
221
+ text-xl
222
+ text-2xl
223
+ font-medium
224
+ font-semibold
225
+ font-bold
226
+ text-center
227
+
228
+ ## Colors
229
+
230
+ bg-white
231
+ bg-black
232
+ bg-gray-50
233
+ bg-gray-100
234
+ text-black
235
+ text-white
236
+ text-gray-500
237
+ text-gray-700
238
+
239
+ ## Borders and Radius
240
+
241
+ border
242
+ border-gray-200
243
+ rounded
244
+ rounded-lg
245
+ rounded-xl
246
+ rounded-2xl
247
+
248
+ ## Shadows
249
+
250
+ shadow
251
+ shadow-md
252
+ shadow-lg
253
+
254
+ ## Buttons
255
+
256
+ bg-black text-white px-4 py-2 rounded-lg
257
+ bg-blue-600 text-white px-4 py-2 rounded-lg
258
+
259
+ ## Forms
260
+
261
+ border rounded-lg px-4 py-2 w-full
262
+ focus:outline-none focus:ring-2 focus:ring-blue-500
263
+
264
+ ## Responsive Examples
265
+
266
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
267
+ </div>
268
+
269
+ <div className="p-4 md:p-8">
270
+ </div>
271
+ `;
272
+
273
+ await fs.writeFile(path.join(target, "tailwind.md"), tailwindCheat);
274
+
275
+ const sqlCheat = `# SQL Cheat Sheet
276
+
277
+ ## Create Database
278
+
279
+ CREATE DATABASE school_db;
280
+ USE school_db;
281
+
282
+ ## Create Table
283
+
284
+ CREATE TABLE Students(
285
+ StudentID INT AUTO_INCREMENT PRIMARY KEY,
286
+ StudentName VARCHAR(100) NOT NULL,
287
+ Age INT
288
+ );
289
+
290
+ ## Insert
291
+
292
+ INSERT INTO Students (StudentName, Age)
293
+ VALUES ('Aime', 20);
294
+
295
+ ## Select All
296
+
297
+ SELECT * FROM Students;
298
+
299
+ ## Select Specific Columns
300
+
301
+ SELECT StudentName, Age FROM Students;
302
+
303
+ ## Filter with WHERE
304
+
305
+ SELECT * FROM Students
306
+ WHERE Age > 18;
307
+
308
+ ## Search with LIKE
309
+
310
+ SELECT * FROM Students
311
+ WHERE StudentName LIKE '%ai%';
312
+
313
+ ## Sort
314
+
315
+ SELECT * FROM Students
316
+ ORDER BY StudentName ASC;
317
+
318
+ SELECT * FROM Students
319
+ ORDER BY Age DESC;
320
+
321
+ ## Limit
322
+
323
+ SELECT * FROM Students
324
+ LIMIT 5;
325
+
326
+ ## Update
327
+
328
+ UPDATE Students
329
+ SET Age = 21
330
+ WHERE StudentID = 1;
331
+
332
+ ## Delete
333
+
334
+ DELETE FROM Students
335
+ WHERE StudentID = 1;
336
+
337
+ ## Count
338
+
339
+ SELECT COUNT(*) AS TotalStudents
340
+ FROM Students;
341
+
342
+ ## Sum
343
+
344
+ SELECT SUM(Amount) AS TotalAmount
345
+ FROM Payments;
346
+
347
+ ## Average
348
+
349
+ SELECT AVG(Marks) AS AverageMarks
350
+ FROM Results;
351
+
352
+ ## Group By
353
+
354
+ SELECT ClassID, COUNT(*) AS TotalStudents
355
+ FROM Students
356
+ GROUP BY ClassID;
357
+
358
+ ## Having
359
+
360
+ SELECT ClassID, COUNT(*) AS TotalStudents
361
+ FROM Students
362
+ GROUP BY ClassID
363
+ HAVING COUNT(*) > 5;
364
+
365
+ ## Inner Join
366
+
367
+ SELECT Students.StudentName, Classes.ClassName
368
+ FROM Students
369
+ INNER JOIN Classes
370
+ ON Students.ClassID = Classes.ClassID;
371
+
372
+ ## Left Join
373
+
374
+ SELECT Students.StudentName, Payments.Amount
375
+ FROM Students
376
+ LEFT JOIN Payments
377
+ ON Students.StudentID = Payments.StudentID;
378
+
379
+ ## Multiple Joins
380
+
381
+ SELECT Students.StudentName, Classes.ClassName, Payments.Amount
382
+ FROM Students
383
+ JOIN Classes ON Students.ClassID = Classes.ClassID
384
+ JOIN Payments ON Students.StudentID = Payments.StudentID;
385
+
386
+ ## Subquery
387
+
388
+ SELECT * FROM Students
389
+ WHERE ClassID IN (
390
+ SELECT ClassID FROM Classes WHERE ClassName = 'S6'
391
+ );
392
+
393
+ ## Between
394
+
395
+ SELECT * FROM Payments
396
+ WHERE Amount BETWEEN 1000 AND 5000;
397
+
398
+ ## Dates
399
+
400
+ SELECT * FROM Orders
401
+ WHERE DATE(CreatedAt) = CURDATE();
402
+
403
+ ## Beginner Exam CRUD Pattern
404
+
405
+ GET all:
406
+ SELECT * FROM TableName;
407
+
408
+ GET one:
409
+ SELECT * FROM TableName WHERE ID = ?;
410
+
411
+ CREATE:
412
+ INSERT INTO TableName (Column1, Column2) VALUES (?, ?);
413
+
414
+ UPDATE:
415
+ UPDATE TableName SET Column1 = ?, Column2 = ? WHERE ID = ?;
416
+
417
+ DELETE:
418
+ DELETE FROM TableName WHERE ID = ?;
419
+ `;
420
+
421
+ await fs.writeFile(path.join(target, "sql.md"), sqlCheat);
422
+
423
+ async function inject(dir) {
424
+ const files = await fs.readdir(dir);
425
+
426
+ for (const file of files) {
427
+ const full = path.join(dir, file);
428
+ const stat = await fs.stat(full);
429
+
430
+ if (stat.isDirectory()) {
431
+ await inject(full);
432
+ } else {
433
+ try {
434
+ let content = await fs.readFile(full, "utf8");
435
+ content = content.replaceAll("__THEME__", answers.theme);
436
+ content = content.replaceAll("__PORT__", answers.serverPort);
437
+ await fs.writeFile(full, content);
438
+ } catch {}
439
+ }
440
+ }
441
+ }
442
+
443
+ await inject(target);
444
+
445
+ console.log(chalk.white("\nProject created successfully.\n"));
446
+
447
+ if (answers.installDeps) {
448
+ console.log(chalk.white("Installing backend dependencies..."));
449
+ const serverInstall = spawnSync("npm", ["install"], {
450
+ cwd: path.join(target, "server"),
451
+ stdio: "inherit",
452
+ shell: true
453
+ });
454
+
455
+ if (serverInstall.status !== 0) {
456
+ console.log(chalk.red("Backend dependency installation failed. You can run npm install manually inside server."));
457
+ }
458
+
459
+ console.log(chalk.white("Installing frontend dependencies..."));
460
+ const clientInstall = spawnSync("npm", ["install"], {
461
+ cwd: path.join(target, "client"),
462
+ stdio: "inherit",
463
+ shell: true
464
+ });
465
+
466
+ if (clientInstall.status !== 0) {
467
+ console.log(chalk.red("Frontend dependency installation failed. You can run npm install manually inside client."));
468
+ }
469
+ }
470
+
471
+ console.log(chalk.white("Next steps:"));
472
+ console.log(chalk.gray(`1. Run schema.sql in MySQL`));
473
+ console.log(chalk.gray(`2. cd ${projectName}/server && npm run dev`));
474
+ console.log(chalk.gray(`3. cd ${projectName}/client && npm run dev`));
package/package.json ADDED
@@ -0,0 +1,29 @@
1
+ {
2
+ "name": "create-parachute",
3
+ "version": "1.0.2",
4
+ "description": "Student-friendly fullstack exam starter generator",
5
+ "type": "module",
6
+ "bin": {
7
+ "create-parachute": "./bin/index.js"
8
+ },
9
+ "scripts": {
10
+ "start": "node bin/index.js"
11
+ },
12
+ "keywords": [
13
+ "cli",
14
+ "student",
15
+ "exam",
16
+ "react",
17
+ "vite",
18
+ "express",
19
+ "mysql",
20
+ "sequelize"
21
+ ],
22
+ "author": "Aime",
23
+ "license": "MIT",
24
+ "dependencies": {
25
+ "chalk": "^5.3.0",
26
+ "fs-extra": "^11.2.0",
27
+ "inquirer": "^9.2.23"
28
+ }
29
+ }
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
+ <title>Parachute</title>
7
+ </head>
8
+ <body>
9
+ <div id="root"></div>
10
+ <script type="module" src="/src/main.jsx"></script>
11
+ </body>
12
+ </html>
@@ -0,0 +1,18 @@
1
+ {
2
+ "private": true,
3
+ "scripts": {
4
+ "dev": "vite",
5
+ "build": "vite build",
6
+ "preview": "vite preview"
7
+ },
8
+ "dependencies": {
9
+ "axios": "^1.7.2",
10
+ "react": "^18.3.1",
11
+ "react-dom": "^18.3.1",
12
+ "react-router-dom": "^6.30.1"
13
+ },
14
+ "devDependencies": {
15
+ "@vitejs/plugin-react": "^4.3.1",
16
+ "vite": "^5.3.4"
17
+ }
18
+ }
@@ -0,0 +1,5 @@
1
+ import Router from "./router";
2
+
3
+ export default function App() {
4
+ return <Router />;
5
+ }
@@ -0,0 +1,6 @@
1
+ import axios from "axios";
2
+
3
+ export const api = axios.create({
4
+ baseURL: "http://localhost:__PORT__",
5
+ withCredentials: true
6
+ });
@@ -0,0 +1,57 @@
1
+ import { Link, useNavigate } from "react-router-dom";
2
+ import { api } from "../api/client";
3
+ import { clearUser, getUser } from "../utils/auth";
4
+
5
+ export default function Navbar() {
6
+ const navigate = useNavigate();
7
+ const user = getUser();
8
+
9
+ const logout = async () => {
10
+ try {
11
+ await api.post("/auth/logout");
12
+ } catch {}
13
+
14
+ clearUser();
15
+ navigate("/login");
16
+ };
17
+
18
+ return (
19
+ <nav style={{
20
+ background: "white",
21
+ borderBottom: "1px solid #e5e7eb",
22
+ padding: "18px 32px",
23
+ display: "flex",
24
+ gap: "24px",
25
+ alignItems: "center"
26
+ }}>
27
+ <strong style={{ marginRight: "12px" }}>Parachute</strong>
28
+
29
+ <Link to="/">Dashboard</Link>
30
+ <Link to="/page1">Page 1</Link>
31
+ <Link to="/page2">Page 2</Link>
32
+ <Link to="/page3">Page 3</Link>
33
+
34
+ <span style={{
35
+ marginLeft: "auto",
36
+ color: "#6b7280",
37
+ fontSize: "14px"
38
+ }}>
39
+ {user?.Username}
40
+ </span>
41
+
42
+ <button
43
+ onClick={logout}
44
+ style={{
45
+ background: "__THEME__",
46
+ color: "white",
47
+ border: "none",
48
+ padding: "10px 16px",
49
+ borderRadius: "10px",
50
+ cursor: "pointer"
51
+ }}
52
+ >
53
+ Logout
54
+ </button>
55
+ </nav>
56
+ );
57
+ }
@@ -0,0 +1,10 @@
1
+ import { Navigate } from "react-router-dom";
2
+ import { isAuthenticated } from "../utils/auth";
3
+
4
+ export default function ProtectedRoute({ children }) {
5
+ if (!isAuthenticated()) {
6
+ return <Navigate to="/login" />;
7
+ }
8
+
9
+ return children;
10
+ }
@@ -0,0 +1,21 @@
1
+ import Navbar from "../components/Navbar";
2
+
3
+ export default function DashboardLayout({ children }) {
4
+ return (
5
+ <div style={{
6
+ minHeight: "100vh",
7
+ background: "#f8fafc",
8
+ fontFamily: "Arial, sans-serif"
9
+ }}>
10
+ <Navbar />
11
+
12
+ <main style={{
13
+ padding: "40px",
14
+ maxWidth: "1100px",
15
+ margin: "0 auto"
16
+ }}>
17
+ {children}
18
+ </main>
19
+ </div>
20
+ );
21
+ }
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import ReactDOM from "react-dom/client";
3
+ import App from "./App";
4
+
5
+ ReactDOM.createRoot(document.getElementById("root")).render(
6
+ <React.StrictMode>
7
+ <App />
8
+ </React.StrictMode>
9
+ );
@@ -0,0 +1,38 @@
1
+ import DashboardLayout from "../layouts/DashboardLayout";
2
+
3
+ export default function Dashboard() {
4
+ return (
5
+ <DashboardLayout>
6
+ <section style={{
7
+ background: "white",
8
+ padding: "32px",
9
+ borderRadius: "18px",
10
+ border: "1px solid #e5e7eb",
11
+ boxShadow: "0 1px 3px rgba(0,0,0,0.06)"
12
+ }}>
13
+ <p style={{
14
+ color: "__THEME__",
15
+ fontWeight: "700",
16
+ marginBottom: "8px"
17
+ }}>
18
+ Ready to customize
19
+ </p>
20
+
21
+ <h1 style={{
22
+ fontSize: "32px",
23
+ marginBottom: "12px"
24
+ }}>
25
+ Welcome Dashboard
26
+ </h1>
27
+
28
+ <p style={{
29
+ color: "#4b5563",
30
+ lineHeight: "1.7"
31
+ }}>
32
+ Start building your own features from this page. Add your forms,
33
+ tables, buttons, and API calls here.
34
+ </p>
35
+ </section>
36
+ </DashboardLayout>
37
+ );
38
+ }