create-aziz-app 2.0.14 → 3.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.
- package/README.md +227 -0
- package/bin/create-aziz-app.js +9 -9
- package/package.json +10 -11
- package/template/README.md +862 -138
- package/template/_framework/boot.js +36 -0
- package/template/_framework/hooks.js +207 -0
- package/template/{modules → _framework}/next-response.js +5 -13
- package/template/_framework/router.js +279 -0
- package/template/_framework/runtime.js +86 -0
- package/template/api/createUser.js +1 -1
- package/template/api/hello.js +8 -17
- package/template/api/loginUser.js +1 -1
- package/template/api/users.js +38 -134
- package/template/app/about/page.js +45 -0
- package/template/app/layout.js +23 -0
- package/template/app/page.js +54 -0
- package/template/app/test/page.js +55 -0
- package/template/components/Footer.js +10 -0
- package/template/components/Navbar.js +30 -0
- package/template/index.html +24 -0
- package/template/package.json +5 -14
- package/template/scripts/dev-server.js +330 -302
- package/template/scripts/live-reload-client.js +0 -1
- package/template/.vscode/settings.json +0 -15
- package/template/api/getUser.js +0 -60
- package/template/api/getUserWithDB.js +0 -65
- package/template/app.config.js +0 -41
- package/template/app.html +0 -55
- package/template/components/Counter.jsx +0 -36
- package/template/components/Footer.jsx +0 -9
- package/template/components/Navbar.jsx +0 -17
- package/template/docs/API-GUIDE.md +0 -196
- package/template/docs/API-ROUTES.md +0 -538
- package/template/docs/AUTO-IMPORT.md +0 -99
- package/template/docs/AUTO-REGISTRATION.md +0 -248
- package/template/docs/CSS-FRAMEWORKS.md +0 -221
- package/template/docs/DEV-SERVER.md +0 -184
- package/template/docs/GETTING-STARTED.md +0 -205
- package/template/docs/HOW-IT-WORKS.md +0 -362
- package/template/docs/NEXTJS-APP-ROUTER.md +0 -536
- package/template/docs/NEXTJS-COMPARISON.md +0 -473
- package/template/docs/QUICK-START.md +0 -111
- package/template/docs/STYLING.md +0 -269
- package/template/docs/TROUBLESHOOTING.md +0 -282
- package/template/modules/README.md +0 -129
- package/template/modules/api.js +0 -44
- package/template/modules/auto-import.js +0 -130
- package/template/modules/router.js +0 -218
- package/template/modules/state.js +0 -248
- package/template/package-lock.json +0 -13
- package/template/pages/About.jsx +0 -48
- package/template/pages/ApiDemo.jsx +0 -209
- package/template/pages/Contact.jsx +0 -25
- package/template/pages/Example.jsx +0 -59
- package/template/pages/Home.jsx +0 -39
- package/template/pages/HooksDemo.jsx +0 -194
- package/template/pages/test.jsx +0 -72
- package/template/scripts/build.js +0 -81
- package/template/scripts/generate-imports.js +0 -88
- package/template/tailwind.config.js +0 -17
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"tailwindCSS.experimental.classRegex": [
|
|
3
|
-
["class\\s*=\\s*['\"`]([^'\"`]*)['\"`]", "([^\\s]+)"]
|
|
4
|
-
],
|
|
5
|
-
"tailwindCSS.includeLanguages": {
|
|
6
|
-
"javascript": "javascript",
|
|
7
|
-
"javascriptreact": "javascript"
|
|
8
|
-
},
|
|
9
|
-
"files.associations": {
|
|
10
|
-
"*.jsx": "javascriptreact"
|
|
11
|
-
},
|
|
12
|
-
"editor.quickSuggestions": {
|
|
13
|
-
"strings": true
|
|
14
|
-
}
|
|
15
|
-
}
|
package/template/api/getUser.js
DELETED
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
// API Route: /api/getUser
|
|
2
|
-
// Next.js App Router style with NextResponse
|
|
3
|
-
|
|
4
|
-
const { NextResponse } = require('../modules/next-response');
|
|
5
|
-
|
|
6
|
-
// Mock database
|
|
7
|
-
const users = [
|
|
8
|
-
{ _id: '1', name: 'Aziz Ahmed', email: 'aziz@example.com', role: 'admin', phone: '123-456-7890' },
|
|
9
|
-
{ _id: '2', name: 'John Doe', email: 'john@example.com', role: 'user', phone: '098-765-4321' },
|
|
10
|
-
{ _id: '3', name: 'Jane Smith', email: 'jane@example.com', role: 'user', phone: '555-123-4567' }
|
|
11
|
-
];
|
|
12
|
-
|
|
13
|
-
// GET handler - Next.js App Router style
|
|
14
|
-
async function GET(request) {
|
|
15
|
-
try {
|
|
16
|
-
// Parse URL and get search params
|
|
17
|
-
const { searchParams } = new URL(request.url);
|
|
18
|
-
const email = searchParams.get('email');
|
|
19
|
-
const id = searchParams.get('id');
|
|
20
|
-
|
|
21
|
-
// Find by email
|
|
22
|
-
if (email) {
|
|
23
|
-
const user = users.find(u => u.email === email);
|
|
24
|
-
if (!user) {
|
|
25
|
-
return NextResponse.json(
|
|
26
|
-
{ error: 'User not found' },
|
|
27
|
-
{ status: 404 }
|
|
28
|
-
);
|
|
29
|
-
}
|
|
30
|
-
return NextResponse.json(user);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// Find by ID
|
|
34
|
-
if (id) {
|
|
35
|
-
const user = users.find(u => u._id === id);
|
|
36
|
-
if (!user) {
|
|
37
|
-
return NextResponse.json(
|
|
38
|
-
{ error: 'User not found' },
|
|
39
|
-
{ status: 404 }
|
|
40
|
-
);
|
|
41
|
-
}
|
|
42
|
-
return NextResponse.json(user);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
// No params provided
|
|
46
|
-
return NextResponse.json(
|
|
47
|
-
{ error: 'Email or ID required' },
|
|
48
|
-
{ status: 400 }
|
|
49
|
-
);
|
|
50
|
-
} catch (error) {
|
|
51
|
-
console.error('Error fetching user:', error);
|
|
52
|
-
return NextResponse.json(
|
|
53
|
-
{ error: 'Failed to fetch user' },
|
|
54
|
-
{ status: 500 }
|
|
55
|
-
);
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// Export the handler
|
|
60
|
-
module.exports = { GET };
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
// API Route: /api/getUserWithDB
|
|
2
|
-
// Complete Next.js App Router style with DB and Model
|
|
3
|
-
|
|
4
|
-
const { NextResponse } = require('../modules/next-response');
|
|
5
|
-
const connectDB = require('../lib/db');
|
|
6
|
-
const User = require('../models/User');
|
|
7
|
-
|
|
8
|
-
// GET handler - Exactly like Next.js!
|
|
9
|
-
async function GET(request) {
|
|
10
|
-
try {
|
|
11
|
-
// Connect to database
|
|
12
|
-
await connectDB();
|
|
13
|
-
|
|
14
|
-
// Parse URL and get search params
|
|
15
|
-
const { searchParams } = new URL(request.url);
|
|
16
|
-
const email = searchParams.get('email');
|
|
17
|
-
const id = searchParams.get('id');
|
|
18
|
-
|
|
19
|
-
// Find by email
|
|
20
|
-
if (email) {
|
|
21
|
-
const user = await User.findOne({ email });
|
|
22
|
-
|
|
23
|
-
if (!user) {
|
|
24
|
-
return NextResponse.json(
|
|
25
|
-
{ error: 'User not found' },
|
|
26
|
-
{ status: 404 }
|
|
27
|
-
);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Return user without sensitive fields
|
|
31
|
-
const { password, ...userData } = user;
|
|
32
|
-
return NextResponse.json(userData);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
// Find by ID
|
|
36
|
-
if (id) {
|
|
37
|
-
const user = await User.findById(id);
|
|
38
|
-
|
|
39
|
-
if (!user) {
|
|
40
|
-
return NextResponse.json(
|
|
41
|
-
{ error: 'User not found' },
|
|
42
|
-
{ status: 404 }
|
|
43
|
-
);
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
// Return user without sensitive fields
|
|
47
|
-
const { password, ...userData } = user;
|
|
48
|
-
return NextResponse.json(userData);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// No params - return error
|
|
52
|
-
return NextResponse.json(
|
|
53
|
-
{ error: 'Email or ID required' },
|
|
54
|
-
{ status: 400 }
|
|
55
|
-
);
|
|
56
|
-
} catch (error) {
|
|
57
|
-
console.error('Error fetching user:', error);
|
|
58
|
-
return NextResponse.json(
|
|
59
|
-
{ error: 'Failed to fetch user' },
|
|
60
|
-
{ status: 500 }
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
module.exports = { GET };
|
package/template/app.config.js
DELETED
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
// ============================================================
|
|
2
|
-
// APP CONFIGURATION
|
|
3
|
-
// Configure what files to auto-import
|
|
4
|
-
// ============================================================
|
|
5
|
-
|
|
6
|
-
// Define all files to be automatically loaded
|
|
7
|
-
window.APP_CONFIG = {
|
|
8
|
-
// API routes to load
|
|
9
|
-
apiRoutes: [
|
|
10
|
-
'api/hello.js',
|
|
11
|
-
'api/users.js'
|
|
12
|
-
],
|
|
13
|
-
|
|
14
|
-
// Components to load
|
|
15
|
-
components: [
|
|
16
|
-
'components/Navbar.jsx',
|
|
17
|
-
'components/Footer.jsx',
|
|
18
|
-
'components/Counter.jsx'
|
|
19
|
-
],
|
|
20
|
-
|
|
21
|
-
// Pages to load
|
|
22
|
-
pages: [
|
|
23
|
-
'pages/Home.jsx',
|
|
24
|
-
'pages/About.jsx',
|
|
25
|
-
'pages/Contact.jsx',
|
|
26
|
-
'pages/test.jsx',
|
|
27
|
-
'pages/ApiDemo.jsx',
|
|
28
|
-
'pages/NewPage.jsx'
|
|
29
|
-
]
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
// HOW TO ADD NEW FILES:
|
|
33
|
-
//
|
|
34
|
-
// 1. Create your new file in the appropriate folder
|
|
35
|
-
// 2. Add the path to the array above
|
|
36
|
-
// 3. Refresh the page - it will auto-load!
|
|
37
|
-
//
|
|
38
|
-
// Example:
|
|
39
|
-
// - New page: Add 'pages/MyNewPage.jsx' to pages array
|
|
40
|
-
// - New component: Add 'components/MyComponent.jsx' to components array
|
|
41
|
-
// - New API route: Add 'api/myroute.js' to apiRoutes array
|
package/template/app.html
DELETED
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html>
|
|
2
|
-
<html lang="en">
|
|
3
|
-
<head>
|
|
4
|
-
<meta charset="UTF-8">
|
|
5
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
|
|
7
|
-
<meta http-equiv="Pragma" content="no-cache">
|
|
8
|
-
<meta http-equiv="Expires" content="0">
|
|
9
|
-
<title>My Aziz App</title>
|
|
10
|
-
|
|
11
|
-
<!-- Global Styles -->
|
|
12
|
-
<link rel="stylesheet" href="styles/globals.css">
|
|
13
|
-
|
|
14
|
-
<!-- Live Reload (only active in development) -->
|
|
15
|
-
<script src="scripts/live-reload-client.js"></script>
|
|
16
|
-
|
|
17
|
-
<!-- Babel compiles JSX in the browser -->
|
|
18
|
-
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
|
|
19
|
-
</head>
|
|
20
|
-
<body>
|
|
21
|
-
|
|
22
|
-
<!-- Navbar is always visible -->
|
|
23
|
-
<div id="navbar"></div>
|
|
24
|
-
|
|
25
|
-
<!-- Page content goes here -->
|
|
26
|
-
<div id="root"></div>
|
|
27
|
-
|
|
28
|
-
<!-- Footer is always visible -->
|
|
29
|
-
<div id="footer"></div>
|
|
30
|
-
|
|
31
|
-
<!-- Load core modules -->
|
|
32
|
-
<script type="text/babel" src="modules/router.js"></script>
|
|
33
|
-
<script type="text/babel" src="modules/state.js"></script>
|
|
34
|
-
<script type="text/babel" src="modules/api.js"></script>
|
|
35
|
-
|
|
36
|
-
<!-- Load shared components -->
|
|
37
|
-
<script type="text/babel" src="components/Counter.jsx"></script>
|
|
38
|
-
<script type="text/babel" src="components/Footer.jsx"></script>
|
|
39
|
-
<script type="text/babel" src="components/Navbar.jsx"></script>
|
|
40
|
-
|
|
41
|
-
<!-- Load pages -->
|
|
42
|
-
<script type="text/babel" src="pages/About.jsx"></script>
|
|
43
|
-
<script type="text/babel" src="pages/ApiDemo.jsx"></script>
|
|
44
|
-
<script type="text/babel" src="pages/Contact.jsx"></script>
|
|
45
|
-
<script type="text/babel" src="pages/Example.jsx"></script>
|
|
46
|
-
<script type="text/babel" src="pages/Home.jsx"></script>
|
|
47
|
-
<script type="text/babel" src="pages/test.jsx"></script>
|
|
48
|
-
|
|
49
|
-
<!-- Start the app -->
|
|
50
|
-
<script type="text/babel">
|
|
51
|
-
startApp();
|
|
52
|
-
</script>
|
|
53
|
-
|
|
54
|
-
</body>
|
|
55
|
-
</html>
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/** @jsx h */
|
|
2
|
-
|
|
3
|
-
// Register this component
|
|
4
|
-
if (window.AutoImport && window.AutoImport.registerComponent) {
|
|
5
|
-
window.AutoImport.registerComponent('Counter', Counter);
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
function Counter({ initialValue = 0 }) {
|
|
9
|
-
// Use the state management system
|
|
10
|
-
const [count, setCount] = window.StateManager ?
|
|
11
|
-
window.StateManager.useState(initialValue) : [initialValue, () => {}];
|
|
12
|
-
|
|
13
|
-
return (
|
|
14
|
-
<div class="card">
|
|
15
|
-
<h3>Counter Component</h3>
|
|
16
|
-
<p>This is a reusable counter component using the new state system.</p>
|
|
17
|
-
|
|
18
|
-
<div class="count-display">{count}</div>
|
|
19
|
-
<div class="counter-actions">
|
|
20
|
-
<button class="btn btn-primary" onClick={() => setCount(count + 1)}>
|
|
21
|
-
+
|
|
22
|
-
</button>
|
|
23
|
-
<button class="btn btn-danger" onClick={() => setCount(count - 1)}>
|
|
24
|
-
-
|
|
25
|
-
</button>
|
|
26
|
-
<button class="btn btn-grey" onClick={() => setCount(initialValue)}>
|
|
27
|
-
Reset
|
|
28
|
-
</button>
|
|
29
|
-
</div>
|
|
30
|
-
|
|
31
|
-
<p style={{ marginTop: '16px', fontSize: '14px', color: '#666' }}>
|
|
32
|
-
Component state is isolated and reactive.
|
|
33
|
-
</p>
|
|
34
|
-
</div>
|
|
35
|
-
);
|
|
36
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
/** @jsx h */
|
|
2
|
-
|
|
3
|
-
function Navbar() {
|
|
4
|
-
const path = getCurrentPath();
|
|
5
|
-
|
|
6
|
-
return (
|
|
7
|
-
<nav>
|
|
8
|
-
<span class="brand" onClick={() => navigate("home")}>⚡ AzizApp</span>
|
|
9
|
-
<a href="#/home" class={path === "home" ? "active" : ""}>Home</a>
|
|
10
|
-
<a href="#/about" class={path === "about" ? "active" : ""}>About</a>
|
|
11
|
-
<a href="#/test" class={path === "test" ? "active" : ""}>Test</a>
|
|
12
|
-
<a href="#/hooks-demo" class={path === "hooks-demo" ? "active" : ""}>Hooks</a>
|
|
13
|
-
<a href="#/api-demo" class={path === "api-demo" ? "active" : ""}>API Demo</a>
|
|
14
|
-
<a href="#/contact" class={path === "contact" ? "active" : ""}>Contact</a>
|
|
15
|
-
</nav>
|
|
16
|
-
);
|
|
17
|
-
}
|
|
@@ -1,196 +0,0 @@
|
|
|
1
|
-
# API Routes Guide
|
|
2
|
-
|
|
3
|
-
## Overview
|
|
4
|
-
|
|
5
|
-
Your app now has a Next.js-like API route system! Create API endpoints in the `api/` folder and call them from your components.
|
|
6
|
-
|
|
7
|
-
## Creating API Routes
|
|
8
|
-
|
|
9
|
-
### Basic Example
|
|
10
|
-
|
|
11
|
-
Create a file in `api/` folder:
|
|
12
|
-
|
|
13
|
-
```javascript
|
|
14
|
-
// api/myroute.js
|
|
15
|
-
registerApiRoute('myroute', async (req, res) => {
|
|
16
|
-
return res.status(200).json({
|
|
17
|
-
message: 'Hello from API!'
|
|
18
|
-
});
|
|
19
|
-
});
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
### Request Object (req)
|
|
23
|
-
|
|
24
|
-
The request object contains:
|
|
25
|
-
- `req.method` - HTTP method (GET, POST, PUT, DELETE)
|
|
26
|
-
- `req.body` - Request body (parsed JSON)
|
|
27
|
-
- `req.query` - Query parameters from URL
|
|
28
|
-
- `req.params` - Route parameters
|
|
29
|
-
|
|
30
|
-
### Response Object (res)
|
|
31
|
-
|
|
32
|
-
The response object has methods:
|
|
33
|
-
- `res.status(code)` - Set HTTP status code
|
|
34
|
-
- `res.json(data)` - Send JSON response
|
|
35
|
-
- `res.send(data)` - Send plain response
|
|
36
|
-
|
|
37
|
-
### Full CRUD Example
|
|
38
|
-
|
|
39
|
-
```javascript
|
|
40
|
-
// api/todos.js
|
|
41
|
-
const todos = [];
|
|
42
|
-
|
|
43
|
-
registerApiRoute('todos', async (req, res) => {
|
|
44
|
-
switch (req.method) {
|
|
45
|
-
case 'GET':
|
|
46
|
-
// Get all todos
|
|
47
|
-
return res.status(200).json(todos);
|
|
48
|
-
|
|
49
|
-
case 'POST':
|
|
50
|
-
// Create new todo
|
|
51
|
-
const newTodo = {
|
|
52
|
-
id: Date.now(),
|
|
53
|
-
title: req.body.title,
|
|
54
|
-
completed: false
|
|
55
|
-
};
|
|
56
|
-
todos.push(newTodo);
|
|
57
|
-
return res.status(201).json(newTodo);
|
|
58
|
-
|
|
59
|
-
case 'PUT':
|
|
60
|
-
// Update todo
|
|
61
|
-
const id = req.body.id;
|
|
62
|
-
const index = todos.findIndex(t => t.id === id);
|
|
63
|
-
if (index !== -1) {
|
|
64
|
-
todos[index] = { ...todos[index], ...req.body };
|
|
65
|
-
return res.status(200).json(todos[index]);
|
|
66
|
-
}
|
|
67
|
-
return res.status(404).json({ error: 'Not found' });
|
|
68
|
-
|
|
69
|
-
case 'DELETE':
|
|
70
|
-
// Delete todo
|
|
71
|
-
const deleteId = req.query.id;
|
|
72
|
-
const deleteIndex = todos.findIndex(t => t.id === parseInt(deleteId));
|
|
73
|
-
if (deleteIndex !== -1) {
|
|
74
|
-
todos.splice(deleteIndex, 1);
|
|
75
|
-
return res.status(200).json({ message: 'Deleted' });
|
|
76
|
-
}
|
|
77
|
-
return res.status(404).json({ error: 'Not found' });
|
|
78
|
-
|
|
79
|
-
default:
|
|
80
|
-
return res.status(405).json({ error: 'Method not allowed' });
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
```
|
|
84
|
-
|
|
85
|
-
## Using API Routes in Components
|
|
86
|
-
|
|
87
|
-
### Basic GET Request
|
|
88
|
-
|
|
89
|
-
```javascript
|
|
90
|
-
const MyComponent = () => {
|
|
91
|
-
const [data, setData] = useState(null);
|
|
92
|
-
|
|
93
|
-
const loadData = async () => {
|
|
94
|
-
const response = await fetchApi('/api/myroute');
|
|
95
|
-
const result = await response.json();
|
|
96
|
-
setData(result);
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
return (
|
|
100
|
-
<div>
|
|
101
|
-
<button onClick={loadData}>Load Data</button>
|
|
102
|
-
{data && <p>{data.message}</p>}
|
|
103
|
-
</div>
|
|
104
|
-
);
|
|
105
|
-
};
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### POST Request
|
|
109
|
-
|
|
110
|
-
```javascript
|
|
111
|
-
const addItem = async () => {
|
|
112
|
-
const response = await fetchApi('/api/todos', {
|
|
113
|
-
method: 'POST',
|
|
114
|
-
body: JSON.stringify({
|
|
115
|
-
title: 'New Todo'
|
|
116
|
-
})
|
|
117
|
-
});
|
|
118
|
-
const result = await response.json();
|
|
119
|
-
console.log('Created:', result);
|
|
120
|
-
};
|
|
121
|
-
```
|
|
122
|
-
|
|
123
|
-
### Query Parameters
|
|
124
|
-
|
|
125
|
-
```javascript
|
|
126
|
-
// Fetch with query params
|
|
127
|
-
const response = await fetchApi('/api/users?id=123&name=John');
|
|
128
|
-
```
|
|
129
|
-
|
|
130
|
-
### DELETE Request
|
|
131
|
-
|
|
132
|
-
```javascript
|
|
133
|
-
const deleteItem = async (id) => {
|
|
134
|
-
const response = await fetchApi(`/api/todos?id=${id}`, {
|
|
135
|
-
method: 'DELETE'
|
|
136
|
-
});
|
|
137
|
-
const result = await response.json();
|
|
138
|
-
console.log(result.message);
|
|
139
|
-
};
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
## Available API Routes
|
|
143
|
-
|
|
144
|
-
### /api/hello
|
|
145
|
-
Simple hello world endpoint
|
|
146
|
-
- **GET** `/api/hello?name=YourName`
|
|
147
|
-
- Returns: `{ message: "Hello, YourName!", timestamp: "...", method: "GET" }`
|
|
148
|
-
|
|
149
|
-
### /api/users
|
|
150
|
-
User management endpoint
|
|
151
|
-
- **GET** `/api/users` - Get all users
|
|
152
|
-
- **GET** `/api/users?id=1` - Get specific user
|
|
153
|
-
- **POST** `/api/users` - Create user (body: `{ name, email }`)
|
|
154
|
-
- **PUT** `/api/users?id=1` - Update user (body: `{ name, email }`)
|
|
155
|
-
- **DELETE** `/api/users?id=1` - Delete user
|
|
156
|
-
|
|
157
|
-
## Tips
|
|
158
|
-
|
|
159
|
-
1. **Mock Data**: Currently, API routes use in-memory data. Replace with real backend calls when ready.
|
|
160
|
-
|
|
161
|
-
2. **Error Handling**: Always wrap API calls in try-catch:
|
|
162
|
-
```javascript
|
|
163
|
-
try {
|
|
164
|
-
const response = await fetchApi('/api/myroute');
|
|
165
|
-
const data = await response.json();
|
|
166
|
-
} catch (error) {
|
|
167
|
-
console.error('API Error:', error);
|
|
168
|
-
}
|
|
169
|
-
```
|
|
170
|
-
|
|
171
|
-
3. **Loading States**: Use loading state for better UX:
|
|
172
|
-
```javascript
|
|
173
|
-
const [loading, setLoading] = useState(false);
|
|
174
|
-
|
|
175
|
-
const loadData = async () => {
|
|
176
|
-
setLoading(true);
|
|
177
|
-
try {
|
|
178
|
-
const response = await fetchApi('/api/data');
|
|
179
|
-
const data = await response.json();
|
|
180
|
-
setData(data);
|
|
181
|
-
} finally {
|
|
182
|
-
setLoading(false);
|
|
183
|
-
}
|
|
184
|
-
};
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
4. **Real Backend**: To connect to a real backend, modify `fetchApi` in `api.js` to use `fetch()` instead of the mock system.
|
|
188
|
-
|
|
189
|
-
## Demo
|
|
190
|
-
|
|
191
|
-
Visit `#/api-demo` in your app to see a live demo of the API system with:
|
|
192
|
-
- GET requests
|
|
193
|
-
- POST requests (create users)
|
|
194
|
-
- DELETE requests
|
|
195
|
-
- Loading states
|
|
196
|
-
- Error handling
|