axiodb 2.10.25 → 2.10.27
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/package.json +1 -1
- package/Document/eslint.config.js +0 -28
- package/Document/index.html +0 -31
- package/Document/package-lock.json +0 -4254
- package/Document/package.json +0 -35
- package/Document/postcss.config.js +0 -6
- package/Document/public/AXioDB.png +0 -0
- package/Document/src/App.tsx +0 -39
- package/Document/src/Assets/AXioDB.png +0 -0
- package/Document/src/components/content/AdvancedFeatures.tsx +0 -318
- package/Document/src/components/content/ApiReference.tsx +0 -319
- package/Document/src/components/content/Community.tsx +0 -203
- package/Document/src/components/content/Comparison.tsx +0 -227
- package/Document/src/components/content/CreateCollection.tsx +0 -59
- package/Document/src/components/content/CreateDatabase.tsx +0 -57
- package/Document/src/components/content/Features.tsx +0 -263
- package/Document/src/components/content/Installation.tsx +0 -67
- package/Document/src/components/content/Introduction.tsx +0 -107
- package/Document/src/components/content/MaintainersZone.tsx +0 -142
- package/Document/src/components/content/PainPoints.tsx +0 -126
- package/Document/src/components/content/Security.tsx +0 -137
- package/Document/src/components/content/Usage.tsx +0 -247
- package/Document/src/components/layout/Header.tsx +0 -154
- package/Document/src/components/layout/Layout.tsx +0 -91
- package/Document/src/components/layout/Sidebar.tsx +0 -185
- package/Document/src/components/ui/Button.tsx +0 -45
- package/Document/src/components/ui/CodeBlock.tsx +0 -41
- package/Document/src/context/ThemeContext.tsx +0 -71
- package/Document/src/hooks/useTheme.tsx +0 -12
- package/Document/src/index.css +0 -3
- package/Document/src/main.tsx +0 -10
- package/Document/src/styles/global.css +0 -18
- package/Document/src/vite-env.d.ts +0 -1
- package/Document/tailwind.config.js +0 -9
- package/Document/tsconfig.app.json +0 -24
- package/Document/tsconfig.node.json +0 -22
- package/Document/vite.config.ts +0 -40
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import { BookOpen } from "lucide-react";
|
|
3
|
-
import CodeBlock from "../ui/CodeBlock";
|
|
4
|
-
import Button from "../ui/Button";
|
|
5
|
-
|
|
6
|
-
const Usage: React.FC = () => {
|
|
7
|
-
const [step, setStep] = useState<
|
|
8
|
-
"selectCodeType" | "selectExampleType" | "showExample"
|
|
9
|
-
>("selectCodeType");
|
|
10
|
-
const [codeType, setCodeType] = useState<"commonjs" | "es6" | null>(null);
|
|
11
|
-
const [exampleType, setExampleType] = useState<
|
|
12
|
-
| "read"
|
|
13
|
-
| "write"
|
|
14
|
-
| "update"
|
|
15
|
-
| "delete"
|
|
16
|
-
| "aggregate"
|
|
17
|
-
| "fastRetrieval"
|
|
18
|
-
| null
|
|
19
|
-
>(null);
|
|
20
|
-
|
|
21
|
-
const examples = {
|
|
22
|
-
commonjs: {
|
|
23
|
-
read: `const documents = await collection.query({ age: { $gt: 20 } }).exec();
|
|
24
|
-
console.log(documents);`,
|
|
25
|
-
write: `const saveStatus = await collection.insert({ name: "Ankan", age: 21, email: "ankan@example.com" });
|
|
26
|
-
console.log(saveStatus);`,
|
|
27
|
-
update: `const updatedDocuments = await collection.update({ name: { $regex: "Ankan" } }).UpdateOne({ name: "Ankan Saha", age: 22 });
|
|
28
|
-
console.log(updatedDocuments);`,
|
|
29
|
-
delete: `const deletedDocuments = await collection.delete({ name: { $regex: "Ankan" } }).deleteOne();
|
|
30
|
-
console.log(deletedDocuments);`,
|
|
31
|
-
aggregate: `const response = await collection.aggregate([
|
|
32
|
-
{ $match: { age: { $gt: 20 }, name: { $regex: "Ankan" } } }, // Filter documents
|
|
33
|
-
{ $group: { _id: "$age", count: { $sum: 1 } } }, // Group by age and count occurrences
|
|
34
|
-
{ $sort: { count: -1 } }, // Sort by count in descending order
|
|
35
|
-
{ $project: { _id: 0, age: "$_id", count: 1 } }, // Project specific fields
|
|
36
|
-
{ $limit: 10 }, // Limit the number of results
|
|
37
|
-
{ $skip: 0 } // Skip a certain number of results
|
|
38
|
-
]).exec();
|
|
39
|
-
console.log(response);`,
|
|
40
|
-
fastRetrieval: `// Retrieve a single document by documentId
|
|
41
|
-
const singleDocument = await collection.query({ documentId: "S4ACDVS6SZ4S6VS" }).exec();
|
|
42
|
-
console.log(singleDocument);
|
|
43
|
-
|
|
44
|
-
// Retrieve multiple documents by an array of documentIds
|
|
45
|
-
const multipleDocuments = await collection.query({ documentId: ["S4ACDVS6SZ4S6VS", "S4ACDVS6SZ4S6VA"] }).exec();
|
|
46
|
-
console.log(multipleDocuments);
|
|
47
|
-
|
|
48
|
-
// Retrieve documents with additional filters
|
|
49
|
-
const filteredDocuments = await collection.query({
|
|
50
|
-
documentId: ["S4ACDVS6SZ4S6VS", "S4ACDVS6SZ4S6VA"],
|
|
51
|
-
age: { $gt: 20 }
|
|
52
|
-
}).exec();
|
|
53
|
-
console.log(filteredDocuments);
|
|
54
|
-
|
|
55
|
-
// Retrieve documents with projection
|
|
56
|
-
const projectedDocuments = await collection.query({
|
|
57
|
-
documentId: ["S4ACDVS6SZ4S6VS", "S4ACDVS6SZ4S6VA"]
|
|
58
|
-
}).setProject({ name: 1, age: 1 }).exec();
|
|
59
|
-
console.log(projectedDocuments);
|
|
60
|
-
|
|
61
|
-
// Retrieve documents with sorting
|
|
62
|
-
const sortedDocuments = await collection.query({
|
|
63
|
-
documentId: ["S4ACDVS6SZ4S6VS", "S4ACDVS6SZ4S6VA"]
|
|
64
|
-
}).Sort({ age: -1 }).exec();
|
|
65
|
-
console.log(sortedDocuments);
|
|
66
|
-
|
|
67
|
-
// Retrieve documents with pagination
|
|
68
|
-
const paginatedDocuments = await collection.query({
|
|
69
|
-
documentId: ["S4ACDVS6SZ4S6VS", "S4ACDVS6SZ4S6VA"]
|
|
70
|
-
}).Limit(2).Skip(1).exec();
|
|
71
|
-
console.log(paginatedDocuments);`,
|
|
72
|
-
},
|
|
73
|
-
es6: {
|
|
74
|
-
read: `const documents = await collection.query({ age: { $gt: 20 } }).exec();
|
|
75
|
-
console.log(documents);`,
|
|
76
|
-
write: `const saveStatus = await collection.insert({ name: "Ankan", age: 21, email: "ankan@example.com" });
|
|
77
|
-
console.log(saveStatus);`,
|
|
78
|
-
update: `const updatedDocuments = await collection.update({ name: { $regex: "Ankan" } }).UpdateOne({ name: "Ankan Saha", age: 22 });
|
|
79
|
-
console.log(updatedDocuments);`,
|
|
80
|
-
delete: `const deletedDocuments = await collection.delete({ name: { $regex: "Ankan" } }).deleteOne();
|
|
81
|
-
console.log(deletedDocuments);`,
|
|
82
|
-
aggregate: `const response = await collection.aggregate([
|
|
83
|
-
{ $match: { age: { $gt: 20 }, name: { $regex: "Ankan" } } }, // Filter documents
|
|
84
|
-
{ $group: { _id: "$age", count: { $sum: 1 } } }, // Group by age and count occurrences
|
|
85
|
-
{ $sort: { count: -1 } }, // Sort by count in descending order
|
|
86
|
-
{ $project: { _id: 0, age: "$_id", count: 1 } }, // Project specific fields
|
|
87
|
-
{ $limit: 10 }, // Limit the number of results
|
|
88
|
-
{ $skip: 0 } // Skip a certain number of results
|
|
89
|
-
]).exec();
|
|
90
|
-
console.log(response);`,
|
|
91
|
-
fastRetrieval: `// Retrieve a single document by documentId
|
|
92
|
-
const singleDocument = await collection.query({ documentId: "S4ACDVS6SZ4S6VS" }).exec();
|
|
93
|
-
console.log(singleDocument);
|
|
94
|
-
|
|
95
|
-
// Retrieve multiple documents by an array of documentIds
|
|
96
|
-
const multipleDocuments = await collection.query({ documentId: ["S4ACDVS6SZ4S6VS", "S4ACDVS6SZ4S6VA"] }).exec();
|
|
97
|
-
console.log(multipleDocuments);
|
|
98
|
-
|
|
99
|
-
// Retrieve documents with additional filters
|
|
100
|
-
const filteredDocuments = await collection.query({
|
|
101
|
-
documentId: ["S4ACDVS6SZ4S6VS", "S4ACDVS6SZ4S6VA"],
|
|
102
|
-
age: { $gt: 20 }
|
|
103
|
-
}).exec();
|
|
104
|
-
console.log(filteredDocuments);
|
|
105
|
-
|
|
106
|
-
// Retrieve documents with projection
|
|
107
|
-
const projectedDocuments = await collection.query({
|
|
108
|
-
documentId: ["S4ACDVS6SZ4S6VS", "S4ACDVS6SZ4S6VA"]
|
|
109
|
-
}).setProject({ name: 1, age: 1 }).exec();
|
|
110
|
-
console.log(projectedDocuments);
|
|
111
|
-
|
|
112
|
-
// Retrieve documents with sorting
|
|
113
|
-
const sortedDocuments = await collection.query({
|
|
114
|
-
documentId: ["S4ACDVS6SZ4S6VS", "S4ACDVS6SZ4S6VA"]
|
|
115
|
-
}).Sort({ age: -1 }).exec();
|
|
116
|
-
console.log(sortedDocuments);
|
|
117
|
-
|
|
118
|
-
// Retrieve documents with pagination
|
|
119
|
-
const paginatedDocuments = await collection.query({
|
|
120
|
-
documentId: ["S4ACDVS6SZ4S6VS", "S4ACDVS6SZ4S6VA"]
|
|
121
|
-
}).Limit(2).Skip(1).exec();
|
|
122
|
-
console.log(paginatedDocuments);`,
|
|
123
|
-
},
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
return (
|
|
127
|
-
<section id="usage" className="pt-12 scroll-mt-20">
|
|
128
|
-
<h2 className="text-3xl font-bold mb-6 flex items-center gap-2">
|
|
129
|
-
<BookOpen className="h-8 w-8 text-green-500" />
|
|
130
|
-
Basic Usage
|
|
131
|
-
</h2>
|
|
132
|
-
|
|
133
|
-
{step === "selectCodeType" && (
|
|
134
|
-
<div className="flex flex-col items-center">
|
|
135
|
-
<p className="text-gray-700 dark:text-gray-300 mb-4">
|
|
136
|
-
Select the code type you want to see:
|
|
137
|
-
</p>
|
|
138
|
-
<div className="flex gap-4">
|
|
139
|
-
<Button
|
|
140
|
-
variant="primary"
|
|
141
|
-
onClick={() => {
|
|
142
|
-
setCodeType("commonjs");
|
|
143
|
-
setStep("selectExampleType");
|
|
144
|
-
}}
|
|
145
|
-
>
|
|
146
|
-
CommonJS
|
|
147
|
-
</Button>
|
|
148
|
-
<Button
|
|
149
|
-
variant="primary"
|
|
150
|
-
onClick={() => {
|
|
151
|
-
setCodeType("es6");
|
|
152
|
-
setStep("selectExampleType");
|
|
153
|
-
}}
|
|
154
|
-
>
|
|
155
|
-
ES6 Modules
|
|
156
|
-
</Button>
|
|
157
|
-
</div>
|
|
158
|
-
</div>
|
|
159
|
-
)}
|
|
160
|
-
|
|
161
|
-
{step === "selectExampleType" && (
|
|
162
|
-
<div className="flex flex-col items-center">
|
|
163
|
-
<p className="text-gray-700 dark:text-gray-300 mb-4">
|
|
164
|
-
Select the example usage you want to see:
|
|
165
|
-
</p>
|
|
166
|
-
<div className="grid grid-cols-2 gap-4">
|
|
167
|
-
<Button
|
|
168
|
-
variant="outline"
|
|
169
|
-
onClick={() => {
|
|
170
|
-
setExampleType("read");
|
|
171
|
-
setStep("showExample");
|
|
172
|
-
}}
|
|
173
|
-
>
|
|
174
|
-
Read
|
|
175
|
-
</Button>
|
|
176
|
-
<Button
|
|
177
|
-
variant="outline"
|
|
178
|
-
onClick={() => {
|
|
179
|
-
setExampleType("write");
|
|
180
|
-
setStep("showExample");
|
|
181
|
-
}}
|
|
182
|
-
>
|
|
183
|
-
Write
|
|
184
|
-
</Button>
|
|
185
|
-
<Button
|
|
186
|
-
variant="outline"
|
|
187
|
-
onClick={() => {
|
|
188
|
-
setExampleType("update");
|
|
189
|
-
setStep("showExample");
|
|
190
|
-
}}
|
|
191
|
-
>
|
|
192
|
-
Update
|
|
193
|
-
</Button>
|
|
194
|
-
<Button
|
|
195
|
-
variant="outline"
|
|
196
|
-
onClick={() => {
|
|
197
|
-
setExampleType("delete");
|
|
198
|
-
setStep("showExample");
|
|
199
|
-
}}
|
|
200
|
-
>
|
|
201
|
-
Delete
|
|
202
|
-
</Button>
|
|
203
|
-
<Button
|
|
204
|
-
variant="outline"
|
|
205
|
-
onClick={() => {
|
|
206
|
-
setExampleType("aggregate");
|
|
207
|
-
setStep("showExample");
|
|
208
|
-
}}
|
|
209
|
-
>
|
|
210
|
-
Aggregate
|
|
211
|
-
</Button>
|
|
212
|
-
<Button
|
|
213
|
-
variant="outline"
|
|
214
|
-
onClick={() => {
|
|
215
|
-
setExampleType("fastRetrieval");
|
|
216
|
-
setStep("showExample");
|
|
217
|
-
}}
|
|
218
|
-
>
|
|
219
|
-
Fast Retrieval
|
|
220
|
-
</Button>
|
|
221
|
-
</div>
|
|
222
|
-
</div>
|
|
223
|
-
)}
|
|
224
|
-
|
|
225
|
-
{step === "showExample" && codeType && exampleType && (
|
|
226
|
-
<div className="flex flex-col items-center">
|
|
227
|
-
<p className="text-gray-700 dark:text-gray-300 mb-4">
|
|
228
|
-
Here is the {exampleType} example for {codeType}:
|
|
229
|
-
</p>
|
|
230
|
-
<CodeBlock
|
|
231
|
-
code={examples[codeType][exampleType]}
|
|
232
|
-
language="javascript"
|
|
233
|
-
/>
|
|
234
|
-
<Button
|
|
235
|
-
variant="outline"
|
|
236
|
-
className="mt-4"
|
|
237
|
-
onClick={() => setStep("selectExampleType")}
|
|
238
|
-
>
|
|
239
|
-
Back to Example Selection
|
|
240
|
-
</Button>
|
|
241
|
-
</div>
|
|
242
|
-
)}
|
|
243
|
-
</section>
|
|
244
|
-
);
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
export default Usage;
|
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect } from "react";
|
|
2
|
-
import { Menu, X, Moon, Sun, Search } from "lucide-react";
|
|
3
|
-
import { Link, useLocation } from "react-router-dom";
|
|
4
|
-
import { useTheme } from "../../hooks/useTheme";
|
|
5
|
-
|
|
6
|
-
interface HeaderProps {
|
|
7
|
-
toggleSidebar: () => void;
|
|
8
|
-
isSidebarOpen: boolean;
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const Header: React.FC<HeaderProps> = ({ toggleSidebar, isSidebarOpen }) => {
|
|
12
|
-
const { theme, toggleTheme } = useTheme();
|
|
13
|
-
const [scrolled, setScrolled] = useState(false);
|
|
14
|
-
const [searchOpen, setSearchOpen] = useState(false);
|
|
15
|
-
const [searchQuery, setSearchQuery] = useState("");
|
|
16
|
-
const location = useLocation();
|
|
17
|
-
|
|
18
|
-
useEffect(() => {
|
|
19
|
-
const handleScroll = () => {
|
|
20
|
-
setScrolled(window.scrollY > 10);
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
window.addEventListener("scroll", handleScroll);
|
|
24
|
-
return () => window.removeEventListener("scroll", handleScroll);
|
|
25
|
-
}, []);
|
|
26
|
-
|
|
27
|
-
return (
|
|
28
|
-
<header
|
|
29
|
-
className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
|
|
30
|
-
scrolled
|
|
31
|
-
? "bg-white dark:bg-gray-900 shadow-md py-2"
|
|
32
|
-
: "bg-transparent py-4"
|
|
33
|
-
}`}
|
|
34
|
-
>
|
|
35
|
-
<div className="container mx-auto px-4">
|
|
36
|
-
<div className="flex items-center justify-between">
|
|
37
|
-
<div className="flex items-center gap-2">
|
|
38
|
-
<button
|
|
39
|
-
className="md:hidden p-2 rounded-md text-gray-500 hover:text-blue-500 dark:text-gray-400 dark:hover:text-blue-400"
|
|
40
|
-
onClick={toggleSidebar}
|
|
41
|
-
aria-label={isSidebarOpen ? "Close sidebar" : "Open sidebar"}
|
|
42
|
-
>
|
|
43
|
-
{isSidebarOpen ? <X size={24} /> : <Menu size={24} />}
|
|
44
|
-
</button>
|
|
45
|
-
|
|
46
|
-
<Link
|
|
47
|
-
to="/"
|
|
48
|
-
className="flex items-center gap-2 text-gray-900 dark:text-white"
|
|
49
|
-
>
|
|
50
|
-
<img src="/AXioDB.png" alt="AxioDB Logo" className="h-8 w-8" />
|
|
51
|
-
<span className="text-xl font-bold">AxioDB</span>
|
|
52
|
-
</Link>
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<div className="hidden md:flex items-center gap-6">
|
|
56
|
-
<Link
|
|
57
|
-
to="/features"
|
|
58
|
-
className={`text-sm font-medium ${
|
|
59
|
-
location.pathname === "/features"
|
|
60
|
-
? "text-blue-500"
|
|
61
|
-
: "text-gray-600 hover:text-blue-500 dark:text-gray-300 dark:hover:text-blue-400"
|
|
62
|
-
}`}
|
|
63
|
-
>
|
|
64
|
-
Features
|
|
65
|
-
</Link>
|
|
66
|
-
<Link
|
|
67
|
-
to="/comparison"
|
|
68
|
-
className={`text-sm font-medium ${
|
|
69
|
-
location.pathname === "/comparison"
|
|
70
|
-
? "text-blue-500"
|
|
71
|
-
: "text-gray-600 hover:text-blue-500 dark:text-gray-300 dark:hover:text-blue-400"
|
|
72
|
-
}`}
|
|
73
|
-
>
|
|
74
|
-
Comparison
|
|
75
|
-
</Link>
|
|
76
|
-
<Link
|
|
77
|
-
to="/installation"
|
|
78
|
-
className={`text-sm font-medium ${
|
|
79
|
-
location.pathname === "/installation"
|
|
80
|
-
? "text-blue-500"
|
|
81
|
-
: "text-gray-600 hover:text-blue-500 dark:text-gray-300 dark:hover:text-blue-400"
|
|
82
|
-
}`}
|
|
83
|
-
>
|
|
84
|
-
Installation
|
|
85
|
-
</Link>
|
|
86
|
-
<Link
|
|
87
|
-
to="/usage"
|
|
88
|
-
className={`text-sm font-medium ${
|
|
89
|
-
location.pathname === "/usage"
|
|
90
|
-
? "text-blue-500"
|
|
91
|
-
: "text-gray-600 hover:text-blue-500 dark:text-gray-300 dark:hover:text-blue-400"
|
|
92
|
-
}`}
|
|
93
|
-
>
|
|
94
|
-
Usage
|
|
95
|
-
</Link>
|
|
96
|
-
<Link
|
|
97
|
-
to="/api-reference"
|
|
98
|
-
className={`text-sm font-medium ${
|
|
99
|
-
location.pathname === "/api-reference"
|
|
100
|
-
? "text-blue-500"
|
|
101
|
-
: "text-gray-600 hover:text-blue-500 dark:text-gray-300 dark:hover:text-blue-400"
|
|
102
|
-
}`}
|
|
103
|
-
>
|
|
104
|
-
API
|
|
105
|
-
</Link>
|
|
106
|
-
<Link
|
|
107
|
-
to="/maintainers-zone"
|
|
108
|
-
className="text-gray-700 dark:text-gray-300 hover:text-blue-500 dark:hover:text-blue-400 transition-colors"
|
|
109
|
-
>
|
|
110
|
-
Maintainer's Zone
|
|
111
|
-
</Link>
|
|
112
|
-
</div>
|
|
113
|
-
|
|
114
|
-
<div className="flex items-center gap-2">
|
|
115
|
-
<div
|
|
116
|
-
className={`relative ${searchOpen ? "w-64" : "w-10"} transition-all duration-300`}
|
|
117
|
-
>
|
|
118
|
-
{searchOpen && (
|
|
119
|
-
<input
|
|
120
|
-
type="text"
|
|
121
|
-
placeholder="Search documentation..."
|
|
122
|
-
className="w-full py-2 px-4 pr-10 rounded-md bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-white focus:outline-none focus:ring-2 focus:ring-blue-500"
|
|
123
|
-
value={searchQuery}
|
|
124
|
-
onChange={(e) => setSearchQuery(e.target.value)}
|
|
125
|
-
/>
|
|
126
|
-
)}
|
|
127
|
-
<button
|
|
128
|
-
className={`p-2 rounded-md text-gray-500 hover:text-blue-500 dark:text-gray-400 dark:hover:text-blue-400 ${searchOpen ? "absolute right-1 top-1/2 transform -translate-y-1/2" : ""}`}
|
|
129
|
-
onClick={() => setSearchOpen(!searchOpen)}
|
|
130
|
-
aria-label={searchOpen ? "Close search" : "Open search"}
|
|
131
|
-
>
|
|
132
|
-
{searchOpen ? <X size={20} /> : <Search size={20} />}
|
|
133
|
-
</button>
|
|
134
|
-
</div>
|
|
135
|
-
|
|
136
|
-
<button
|
|
137
|
-
className="p-2 rounded-md text-gray-500 hover:text-blue-500 dark:text-gray-400 dark:hover:text-blue-400"
|
|
138
|
-
onClick={toggleTheme}
|
|
139
|
-
aria-label={
|
|
140
|
-
theme === "dark"
|
|
141
|
-
? "Switch to light mode"
|
|
142
|
-
: "Switch to dark mode"
|
|
143
|
-
}
|
|
144
|
-
>
|
|
145
|
-
{theme === "dark" ? <Sun size={24} /> : <Moon size={24} />}
|
|
146
|
-
</button>
|
|
147
|
-
</div>
|
|
148
|
-
</div>
|
|
149
|
-
</div>
|
|
150
|
-
</header>
|
|
151
|
-
);
|
|
152
|
-
};
|
|
153
|
-
|
|
154
|
-
export default Header;
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import React, { useState, useEffect } from "react";
|
|
2
|
-
import Header from "./Header";
|
|
3
|
-
import Sidebar from "./Sidebar";
|
|
4
|
-
import { ThemeProvider } from "../../context/ThemeContext";
|
|
5
|
-
|
|
6
|
-
interface LayoutProps {
|
|
7
|
-
children: React.ReactNode;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
const Layout: React.FC<LayoutProps> = ({ children }) => {
|
|
11
|
-
const [isSidebarOpen, setIsSidebarOpen] = useState(false);
|
|
12
|
-
const [activeSection, setActiveSection] = useState("introduction");
|
|
13
|
-
|
|
14
|
-
// Close sidebar when clicking outside on mobile
|
|
15
|
-
useEffect(() => {
|
|
16
|
-
const handleClickOutside = (event: MouseEvent) => {
|
|
17
|
-
const sidebar = document.querySelector("aside");
|
|
18
|
-
const sidebarButton = document.querySelector(
|
|
19
|
-
'button[aria-label="Open sidebar"]',
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
if (
|
|
23
|
-
sidebar &&
|
|
24
|
-
!sidebar.contains(event.target as Node) &&
|
|
25
|
-
sidebarButton &&
|
|
26
|
-
!sidebarButton.contains(event.target as Node) &&
|
|
27
|
-
window.innerWidth < 768
|
|
28
|
-
) {
|
|
29
|
-
setIsSidebarOpen(false);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
|
|
33
|
-
document.addEventListener("mousedown", handleClickOutside);
|
|
34
|
-
return () => {
|
|
35
|
-
document.removeEventListener("mousedown", handleClickOutside);
|
|
36
|
-
};
|
|
37
|
-
}, []);
|
|
38
|
-
|
|
39
|
-
// Track active section based on scroll position
|
|
40
|
-
useEffect(() => {
|
|
41
|
-
const handleScroll = () => {
|
|
42
|
-
const scrollPosition = window.scrollY + 100;
|
|
43
|
-
|
|
44
|
-
// Get all section elements
|
|
45
|
-
const sections = document.querySelectorAll("section[id]");
|
|
46
|
-
|
|
47
|
-
// Find the current section
|
|
48
|
-
for (let i = sections.length - 1; i >= 0; i--) {
|
|
49
|
-
const section = sections[i];
|
|
50
|
-
const sectionTop = (section as HTMLElement).offsetTop;
|
|
51
|
-
|
|
52
|
-
if (scrollPosition >= sectionTop) {
|
|
53
|
-
setActiveSection(section.id);
|
|
54
|
-
break;
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
window.addEventListener("scroll", handleScroll);
|
|
60
|
-
return () => {
|
|
61
|
-
window.removeEventListener("scroll", handleScroll);
|
|
62
|
-
};
|
|
63
|
-
}, []);
|
|
64
|
-
|
|
65
|
-
return (
|
|
66
|
-
<ThemeProvider>
|
|
67
|
-
<div className="min-h-screen bg-white dark:bg-gray-950 text-gray-900 dark:text-gray-100">
|
|
68
|
-
<Header
|
|
69
|
-
toggleSidebar={() => setIsSidebarOpen(!isSidebarOpen)}
|
|
70
|
-
isSidebarOpen={isSidebarOpen}
|
|
71
|
-
/>
|
|
72
|
-
|
|
73
|
-
<div className="flex">
|
|
74
|
-
<Sidebar
|
|
75
|
-
isOpen={isSidebarOpen}
|
|
76
|
-
activeSection={activeSection}
|
|
77
|
-
setActiveSection={setActiveSection}
|
|
78
|
-
/>
|
|
79
|
-
|
|
80
|
-
<main className="flex-1 pt-16 pb-16 transition-all duration-300 md:ml-64">
|
|
81
|
-
<div className="container mx-auto px-4 py-8 max-w-4xl">
|
|
82
|
-
{children}
|
|
83
|
-
</div>
|
|
84
|
-
</main>
|
|
85
|
-
</div>
|
|
86
|
-
</div>
|
|
87
|
-
</ThemeProvider>
|
|
88
|
-
);
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
export default Layout;
|
|
@@ -1,185 +0,0 @@
|
|
|
1
|
-
import React, { useState } from "react";
|
|
2
|
-
import { useNavigate, useLocation, Link } from "react-router-dom";
|
|
3
|
-
import { ChevronDown, ChevronRight } from "lucide-react";
|
|
4
|
-
|
|
5
|
-
interface SidebarSection {
|
|
6
|
-
title: string;
|
|
7
|
-
items: { id: string; label: string; path: string }[];
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface SidebarProps {
|
|
11
|
-
isOpen: boolean;
|
|
12
|
-
activeSection: string;
|
|
13
|
-
setActiveSection: (section: string) => void;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
const sidebarSections: SidebarSection[] = [
|
|
17
|
-
{
|
|
18
|
-
title: "Getting Started",
|
|
19
|
-
items: [
|
|
20
|
-
{ id: "introduction", label: "Introduction", path: "/" },
|
|
21
|
-
{ id: "features", label: "Features", path: "/features" },
|
|
22
|
-
{ id: "pain-points", label: "Pain Points", path: "/#pain-points" },
|
|
23
|
-
{
|
|
24
|
-
id: "comparison",
|
|
25
|
-
label: "Performance Comparison",
|
|
26
|
-
path: "/comparison",
|
|
27
|
-
},
|
|
28
|
-
{
|
|
29
|
-
id: "limitations",
|
|
30
|
-
label: "Current Limitations",
|
|
31
|
-
path: "/features#limitations",
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
id: "future-plans",
|
|
35
|
-
label: "Future Plans",
|
|
36
|
-
path: "/features#future-plans",
|
|
37
|
-
},
|
|
38
|
-
],
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
title: "Installation & Setup",
|
|
42
|
-
items: [
|
|
43
|
-
{ id: "installation", label: "Installation", path: "/installation" },
|
|
44
|
-
{
|
|
45
|
-
id: "create-database",
|
|
46
|
-
label: "Create Database",
|
|
47
|
-
path: "/create-database",
|
|
48
|
-
},
|
|
49
|
-
{
|
|
50
|
-
id: "create-collection",
|
|
51
|
-
label: "Create Collection",
|
|
52
|
-
path: "/create-collection",
|
|
53
|
-
},
|
|
54
|
-
],
|
|
55
|
-
},
|
|
56
|
-
{
|
|
57
|
-
title: "Basic Usage",
|
|
58
|
-
items: [{ id: "operations", label: "Operations", path: "/usage" }],
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
title: "Advanced Topics",
|
|
62
|
-
items: [
|
|
63
|
-
{
|
|
64
|
-
id: "advanced-features",
|
|
65
|
-
label: "Advanced Features",
|
|
66
|
-
path: "/advanced-features",
|
|
67
|
-
},
|
|
68
|
-
{ id: "api-reference", label: "API Reference", path: "/api-reference" },
|
|
69
|
-
{ id: "security", label: "Security", path: "/security" },
|
|
70
|
-
],
|
|
71
|
-
},
|
|
72
|
-
{
|
|
73
|
-
title: "Community",
|
|
74
|
-
items: [
|
|
75
|
-
{
|
|
76
|
-
id: "contributing",
|
|
77
|
-
label: "Contributing",
|
|
78
|
-
path: "/community#contributing",
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
id: "acknowledgments",
|
|
82
|
-
label: "Acknowledgments",
|
|
83
|
-
path: "/community#acknowledgments",
|
|
84
|
-
},
|
|
85
|
-
],
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
title: "Maintainer's Zone",
|
|
89
|
-
items: [
|
|
90
|
-
{
|
|
91
|
-
id: "maintainers-zone",
|
|
92
|
-
label: "Maintainer's Zone",
|
|
93
|
-
path: "/maintainers-zone",
|
|
94
|
-
},
|
|
95
|
-
],
|
|
96
|
-
},
|
|
97
|
-
];
|
|
98
|
-
|
|
99
|
-
const Sidebar: React.FC<SidebarProps> = ({ isOpen, setActiveSection }) => {
|
|
100
|
-
const [expandedSections, setExpandedSections] = useState<string[]>(
|
|
101
|
-
sidebarSections.map((section) => section.title),
|
|
102
|
-
);
|
|
103
|
-
const navigate = useNavigate();
|
|
104
|
-
const location = useLocation();
|
|
105
|
-
|
|
106
|
-
const toggleSection = (section: string) => {
|
|
107
|
-
setExpandedSections((prev) =>
|
|
108
|
-
prev.includes(section)
|
|
109
|
-
? prev.filter((s) => s !== section)
|
|
110
|
-
: [...prev, section],
|
|
111
|
-
);
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
const handleNavClick = (path: string, id: string) => {
|
|
115
|
-
setActiveSection(id);
|
|
116
|
-
navigate(path);
|
|
117
|
-
|
|
118
|
-
if (path.includes("#")) {
|
|
119
|
-
setTimeout(() => {
|
|
120
|
-
const element = document.getElementById(id);
|
|
121
|
-
if (element) {
|
|
122
|
-
element.scrollIntoView({ behavior: "smooth" });
|
|
123
|
-
}
|
|
124
|
-
}, 100);
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
|
-
|
|
128
|
-
return (
|
|
129
|
-
<aside
|
|
130
|
-
className={`fixed top-16 left-0 h-[calc(100vh-4rem)] bg-gray-50 dark:bg-gray-900 shadow-lg transition-all duration-300 overflow-y-auto z-40 ${
|
|
131
|
-
isOpen
|
|
132
|
-
? "w-64 translate-x-0"
|
|
133
|
-
: "w-64 -translate-x-full md:translate-x-0 md:w-64"
|
|
134
|
-
}`}
|
|
135
|
-
>
|
|
136
|
-
<nav className="p-4">
|
|
137
|
-
<div className="mb-6">
|
|
138
|
-
<div className="text-lg font-semibold text-gray-900 dark:text-white mb-2">
|
|
139
|
-
Documentation
|
|
140
|
-
</div>
|
|
141
|
-
<div className="border-b border-gray-200 dark:border-gray-700 mb-4"></div>
|
|
142
|
-
</div>
|
|
143
|
-
|
|
144
|
-
{sidebarSections.map((section) => (
|
|
145
|
-
<div key={section.title} className="mb-4">
|
|
146
|
-
<button
|
|
147
|
-
className="flex items-center justify-between w-full text-left text-gray-600 hover:text-blue-500 dark:text-gray-300 dark:hover:text-blue-400 font-medium"
|
|
148
|
-
onClick={() => toggleSection(section.title)}
|
|
149
|
-
>
|
|
150
|
-
<span>{section.title}</span>
|
|
151
|
-
{expandedSections.includes(section.title) ? (
|
|
152
|
-
<ChevronDown size={18} />
|
|
153
|
-
) : (
|
|
154
|
-
<ChevronRight size={18} />
|
|
155
|
-
)}
|
|
156
|
-
</button>
|
|
157
|
-
|
|
158
|
-
{expandedSections.includes(section.title) && (
|
|
159
|
-
<ul className="mt-2 space-y-1 pl-4">
|
|
160
|
-
{section.items.map((item) => (
|
|
161
|
-
<li key={item.id}>
|
|
162
|
-
<Link
|
|
163
|
-
to={item.path}
|
|
164
|
-
className={`block py-1 text-sm ${
|
|
165
|
-
location.pathname === item.path ||
|
|
166
|
-
(location.hash && item.path.includes(location.hash))
|
|
167
|
-
? "text-blue-500 font-medium"
|
|
168
|
-
: "text-gray-600 dark:text-gray-400 hover:text-blue-500 dark:hover:text-blue-400"
|
|
169
|
-
}`}
|
|
170
|
-
onClick={() => handleNavClick(item.path, item.id)}
|
|
171
|
-
>
|
|
172
|
-
{item.label}
|
|
173
|
-
</Link>
|
|
174
|
-
</li>
|
|
175
|
-
))}
|
|
176
|
-
</ul>
|
|
177
|
-
)}
|
|
178
|
-
</div>
|
|
179
|
-
))}
|
|
180
|
-
</nav>
|
|
181
|
-
</aside>
|
|
182
|
-
);
|
|
183
|
-
};
|
|
184
|
-
|
|
185
|
-
export default Sidebar;
|