@geenius/docs 0.1.0 → 0.4.1
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/CHANGELOG.md +13 -0
- package/README.md +53 -1
- package/package.json +101 -13
- package/packages/convex/dist/index.d.ts +503 -0
- package/packages/convex/dist/index.js +482 -0
- package/packages/convex/dist/index.js.map +1 -0
- package/packages/react/dist/index.d.ts +439 -0
- package/packages/react/dist/index.js +4954 -0
- package/packages/react/dist/index.js.map +1 -0
- package/packages/react-css/{src/styles.css → dist/index.css} +183 -223
- package/packages/react-css/dist/index.css.map +1 -0
- package/packages/react-css/dist/index.d.ts +443 -0
- package/packages/react-css/dist/index.js +5058 -0
- package/packages/react-css/dist/index.js.map +1 -0
- package/packages/shared/dist/index.d.ts +684 -0
- package/packages/shared/dist/index.js +788 -0
- package/packages/shared/dist/index.js.map +1 -0
- package/packages/solidjs/dist/index.d.ts +435 -0
- package/packages/solidjs/dist/index.js +4584 -0
- package/packages/solidjs/dist/index.js.map +1 -0
- package/packages/solidjs-css/{src/styles.css → dist/index.css} +183 -223
- package/packages/solidjs-css/dist/index.css.map +1 -0
- package/packages/solidjs-css/dist/index.d.ts +432 -0
- package/packages/solidjs-css/dist/index.js +4934 -0
- package/packages/solidjs-css/dist/index.js.map +1 -0
- package/.changeset/config.json +0 -11
- package/.github/CODEOWNERS +0 -1
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -16
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -11
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -10
- package/.github/dependabot.yml +0 -11
- package/.github/workflows/ci.yml +0 -23
- package/.github/workflows/release.yml +0 -29
- package/.nvmrc +0 -1
- package/.project/ACCOUNT.yaml +0 -4
- package/.project/IDEAS.yaml +0 -7
- package/.project/PROJECT.yaml +0 -11
- package/.project/ROADMAP.yaml +0 -15
- package/CODE_OF_CONDUCT.md +0 -16
- package/CONTRIBUTING.md +0 -26
- package/SECURITY.md +0 -15
- package/SUPPORT.md +0 -8
- package/packages/convex/README.md +0 -1
- package/packages/convex/package.json +0 -12
- package/packages/convex/src/convex.config.ts +0 -3
- package/packages/convex/src/index.ts +0 -3
- package/packages/convex/src/mutations.ts +0 -270
- package/packages/convex/src/queries.ts +0 -175
- package/packages/convex/src/schema.ts +0 -55
- package/packages/react/README.md +0 -1
- package/packages/react/package.json +0 -36
- package/packages/react/src/DocsLayout.tsx +0 -116
- package/packages/react/src/DocsProvider.tsx +0 -93
- package/packages/react/src/RouterDocsContent.tsx +0 -148
- package/packages/react/src/RouterDocsLayout.tsx +0 -161
- package/packages/react/src/components/Breadcrumbs.tsx +0 -34
- package/packages/react/src/components/DocPage.tsx +0 -191
- package/packages/react/src/components/DocSearch.tsx +0 -140
- package/packages/react/src/components/DocSidebar.tsx +0 -86
- package/packages/react/src/components/DocsLayout.tsx +0 -62
- package/packages/react/src/components/EditButton.tsx +0 -26
- package/packages/react/src/components/PageNavigation.tsx +0 -45
- package/packages/react/src/components/TableOfContents.tsx +0 -46
- package/packages/react/src/components/VersionSelector.tsx +0 -60
- package/packages/react/src/components/index.ts +0 -9
- package/packages/react/src/hooks/index.ts +0 -8
- package/packages/react/src/hooks/useDocSearch.ts +0 -55
- package/packages/react/src/hooks/useDocs.ts +0 -57
- package/packages/react/src/hooks/useDocsAdmin.ts +0 -151
- package/packages/react/src/hooks/useTableOfContents.ts +0 -66
- package/packages/react/src/index.ts +0 -38
- package/packages/react/src/pages/DocSearchPage.tsx +0 -129
- package/packages/react/src/pages/DocViewPage.tsx +0 -158
- package/packages/react/src/pages/DocsAdminPage.tsx +0 -330
- package/packages/react/src/pages/DocsIndexPage.tsx +0 -172
- package/packages/react/src/pages/index.ts +0 -4
- package/packages/react/src/useDocs.ts +0 -58
- package/packages/react/tsup.config.ts +0 -12
- package/packages/react-css/README.md +0 -1
- package/packages/react-css/package.json +0 -37
- package/packages/react-css/src/DocsLayout.tsx +0 -117
- package/packages/react-css/src/DocsProvider.tsx +0 -93
- package/packages/react-css/src/RouterDocsContent.tsx +0 -60
- package/packages/react-css/src/RouterDocsLayout.tsx +0 -101
- package/packages/react-css/src/components/DocPage.tsx +0 -21
- package/packages/react-css/src/components/DocSearch.tsx +0 -55
- package/packages/react-css/src/components/DocSidebar.tsx +0 -56
- package/packages/react-css/src/components/DocsLayout.tsx +0 -28
- package/packages/react-css/src/components/common.tsx +0 -93
- package/packages/react-css/src/components/index.ts +0 -5
- package/packages/react-css/src/hooks/index.ts +0 -2
- package/packages/react-css/src/index.ts +0 -6
- package/packages/react-css/src/index.tsx +0 -3
- package/packages/react-css/src/pages/DocViewPage.tsx +0 -78
- package/packages/react-css/src/pages/DocsAdminPage.tsx +0 -101
- package/packages/react-css/src/pages/DocsIndexPage.tsx +0 -68
- package/packages/react-css/src/pages/index.ts +0 -3
- package/packages/react-css/src/useDocs.ts +0 -58
- package/packages/react-css/tsconfig.json +0 -19
- package/packages/react-css/tsup.config.ts +0 -10
- package/packages/shared/README.md +0 -1
- package/packages/shared/package.json +0 -31
- package/packages/shared/src/__tests__/docs.test.ts +0 -69
- package/packages/shared/src/config.ts +0 -80
- package/packages/shared/src/index.ts +0 -179
- package/packages/shared/src/providers/astro.ts +0 -94
- package/packages/shared/src/providers/fumadocs.ts +0 -116
- package/packages/shared/src/providers/internal.ts +0 -80
- package/packages/shared/src/types.ts +0 -73
- package/packages/shared/tsconfig.json +0 -18
- package/packages/shared/tsup.config.ts +0 -12
- package/packages/shared/vitest.config.ts +0 -4
- package/packages/solidjs/README.md +0 -1
- package/packages/solidjs/package.json +0 -33
- package/packages/solidjs/src/DocsLayout.tsx +0 -87
- package/packages/solidjs/src/DocsProvider.tsx +0 -95
- package/packages/solidjs/src/RouterDocsContent.tsx +0 -147
- package/packages/solidjs/src/RouterDocsLayout.tsx +0 -161
- package/packages/solidjs/src/components/Breadcrumbs.tsx +0 -27
- package/packages/solidjs/src/components/DocPage.tsx +0 -110
- package/packages/solidjs/src/components/DocSearch.tsx +0 -81
- package/packages/solidjs/src/components/DocSidebar.tsx +0 -92
- package/packages/solidjs/src/components/DocsLayout.tsx +0 -38
- package/packages/solidjs/src/components/EditButton.tsx +0 -15
- package/packages/solidjs/src/components/PageNavigation.tsx +0 -31
- package/packages/solidjs/src/components/TableOfContents.tsx +0 -41
- package/packages/solidjs/src/components/VersionSelector.tsx +0 -30
- package/packages/solidjs/src/components/index.ts +0 -9
- package/packages/solidjs/src/createDocs.ts +0 -62
- package/packages/solidjs/src/index.ts +0 -28
- package/packages/solidjs/src/pages/DocSearchPage.tsx +0 -72
- package/packages/solidjs/src/pages/DocViewPage.tsx +0 -80
- package/packages/solidjs/src/pages/DocsAdminPage.tsx +0 -123
- package/packages/solidjs/src/pages/DocsIndexPage.tsx +0 -85
- package/packages/solidjs/src/pages/index.ts +0 -4
- package/packages/solidjs/src/primitives/createDocSearch.ts +0 -42
- package/packages/solidjs/src/primitives/createDocs.ts +0 -35
- package/packages/solidjs/src/primitives/createDocsAdmin.ts +0 -63
- package/packages/solidjs/src/primitives/createTableOfContents.ts +0 -51
- package/packages/solidjs/src/primitives/index.ts +0 -4
- package/packages/solidjs/tsup.config.ts +0 -12
- package/packages/solidjs-css/README.md +0 -1
- package/packages/solidjs-css/package.json +0 -36
- package/packages/solidjs-css/src/DocsLayout.tsx +0 -106
- package/packages/solidjs-css/src/DocsProvider.tsx +0 -95
- package/packages/solidjs-css/src/RouterDocsContent.tsx +0 -54
- package/packages/solidjs-css/src/RouterDocsLayout.tsx +0 -104
- package/packages/solidjs-css/src/createDocs.ts +0 -62
- package/packages/solidjs-css/src/index.ts +0 -7
- package/packages/solidjs-css/src/index.tsx +0 -17
- package/packages/solidjs-css/src/pages/DocViewPage.tsx +0 -111
- package/packages/solidjs-css/src/pages/DocsAdminPage.tsx +0 -332
- package/packages/solidjs-css/src/pages/DocsIndexPage.tsx +0 -116
- package/packages/solidjs-css/src/pages/index.ts +0 -3
- package/packages/solidjs-css/src/primitives/index.ts +0 -1
- package/packages/solidjs-css/tsconfig.json +0 -20
- package/packages/solidjs-css/tsup.config.ts +0 -10
- package/pnpm-workspace.yaml +0 -2
|
@@ -1,175 +0,0 @@
|
|
|
1
|
-
import { v } from "convex/values";
|
|
2
|
-
import { query } from "./_generated/server.js";
|
|
3
|
-
|
|
4
|
-
export const listSections = query({
|
|
5
|
-
args: { access: v.optional(v.string()) },
|
|
6
|
-
returns: v.array(v.any()),
|
|
7
|
-
handler: async (ctx, args) => {
|
|
8
|
-
let sections = await ctx.db
|
|
9
|
-
.query("doc_sections")
|
|
10
|
-
.withIndex("by_order")
|
|
11
|
-
.collect();
|
|
12
|
-
|
|
13
|
-
if (args.access) {
|
|
14
|
-
sections = sections.filter((s) => s.access === args.access);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return sections.sort((a, b) => a.order - b.order);
|
|
18
|
-
},
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
export const getSection = query({
|
|
22
|
-
args: { sectionId: v.id("doc_sections") },
|
|
23
|
-
returns: v.any(),
|
|
24
|
-
handler: async (ctx, args) => {
|
|
25
|
-
return await ctx.db.get(args.sectionId);
|
|
26
|
-
},
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
export const listPagesBySection = query({
|
|
30
|
-
args: {
|
|
31
|
-
sectionId: v.id("doc_sections"),
|
|
32
|
-
status: v.optional(v.string()),
|
|
33
|
-
},
|
|
34
|
-
returns: v.array(v.any()),
|
|
35
|
-
handler: async (ctx, args) => {
|
|
36
|
-
let pages = await ctx.db
|
|
37
|
-
.query("doc_pages")
|
|
38
|
-
.withIndex("by_sectionId", (q) => q.eq("sectionId", args.sectionId))
|
|
39
|
-
.collect();
|
|
40
|
-
|
|
41
|
-
if (args.status) {
|
|
42
|
-
pages = pages.filter((p) => p.status === args.status);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
return pages.sort((a, b) => a.order - b.order);
|
|
46
|
-
},
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
export const getPage = query({
|
|
50
|
-
args: {
|
|
51
|
-
sectionId: v.id("doc_sections"),
|
|
52
|
-
slug: v.string(),
|
|
53
|
-
},
|
|
54
|
-
returns: v.any(),
|
|
55
|
-
handler: async (ctx, args) => {
|
|
56
|
-
const pages = await ctx.db
|
|
57
|
-
.query("doc_pages")
|
|
58
|
-
.withIndex("by_sectionId", (q) => q.eq("sectionId", args.sectionId))
|
|
59
|
-
.collect();
|
|
60
|
-
|
|
61
|
-
return pages.find((p) => p.slug === args.slug) ?? null;
|
|
62
|
-
},
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
export const getPageById = query({
|
|
66
|
-
args: { pageId: v.id("doc_pages") },
|
|
67
|
-
returns: v.any(),
|
|
68
|
-
handler: async (ctx, args) => {
|
|
69
|
-
return await ctx.db.get(args.pageId);
|
|
70
|
-
},
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
export const searchPages = query({
|
|
74
|
-
args: {
|
|
75
|
-
query: v.string(),
|
|
76
|
-
access: v.optional(v.string()),
|
|
77
|
-
},
|
|
78
|
-
returns: v.array(v.any()),
|
|
79
|
-
handler: async (ctx, args) => {
|
|
80
|
-
const q = args.query.toLowerCase();
|
|
81
|
-
if (!q) return [];
|
|
82
|
-
|
|
83
|
-
let pages = await ctx.db.query("doc_pages").collect();
|
|
84
|
-
|
|
85
|
-
if (args.access) {
|
|
86
|
-
pages = pages.filter((p) => p.access === args.access);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
const results = pages
|
|
90
|
-
.filter(
|
|
91
|
-
(p) =>
|
|
92
|
-
p.title.toLowerCase().includes(q) ||
|
|
93
|
-
p.content.toLowerCase().includes(q) ||
|
|
94
|
-
p.tags.some((t: string) => t.toLowerCase().includes(q))
|
|
95
|
-
)
|
|
96
|
-
.slice(0, 20);
|
|
97
|
-
|
|
98
|
-
return results;
|
|
99
|
-
},
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
export const getFullTree = query({
|
|
103
|
-
args: { access: v.optional(v.string()) },
|
|
104
|
-
returns: v.any(),
|
|
105
|
-
handler: async (ctx, args) => {
|
|
106
|
-
let sections = await ctx.db
|
|
107
|
-
.query("doc_sections")
|
|
108
|
-
.withIndex("by_order")
|
|
109
|
-
.collect();
|
|
110
|
-
|
|
111
|
-
if (args.access) {
|
|
112
|
-
sections = sections.filter((s) => s.access === args.access);
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
sections.sort((a, b) => a.order - b.order);
|
|
116
|
-
|
|
117
|
-
const tree = [];
|
|
118
|
-
for (const section of sections) {
|
|
119
|
-
const pages = await ctx.db
|
|
120
|
-
.query("doc_pages")
|
|
121
|
-
.withIndex("by_sectionId", (q) => q.eq("sectionId", section._id))
|
|
122
|
-
.collect();
|
|
123
|
-
|
|
124
|
-
const publishedPages = pages
|
|
125
|
-
.filter((p) => p.status === "published")
|
|
126
|
-
.sort((a, b) => a.order - b.order);
|
|
127
|
-
|
|
128
|
-
tree.push({
|
|
129
|
-
...section,
|
|
130
|
-
id: section._id,
|
|
131
|
-
pages: publishedPages.map((p) => ({ ...p, id: p._id })),
|
|
132
|
-
pageCount: publishedPages.length,
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
return tree;
|
|
137
|
-
},
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
export const getRecentPages = query({
|
|
141
|
-
args: {
|
|
142
|
-
limit: v.optional(v.number()),
|
|
143
|
-
access: v.optional(v.string()),
|
|
144
|
-
},
|
|
145
|
-
returns: v.array(v.any()),
|
|
146
|
-
handler: async (ctx, args) => {
|
|
147
|
-
let pages = await ctx.db.query("doc_pages").collect();
|
|
148
|
-
|
|
149
|
-
pages = pages.filter((p) => p.status === "published");
|
|
150
|
-
|
|
151
|
-
if (args.access) {
|
|
152
|
-
pages = pages.filter((p) => p.access === args.access);
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
pages.sort((a, b) => b.updatedAt - a.updatedAt);
|
|
156
|
-
|
|
157
|
-
return pages.slice(0, args.limit ?? 10).map((p) => ({ ...p, id: p._id }));
|
|
158
|
-
},
|
|
159
|
-
});
|
|
160
|
-
|
|
161
|
-
export const getPageVersions = query({
|
|
162
|
-
args: { slug: v.string() },
|
|
163
|
-
returns: v.array(v.any()),
|
|
164
|
-
handler: async (ctx, args) => {
|
|
165
|
-
const pages = await ctx.db
|
|
166
|
-
.query("doc_pages")
|
|
167
|
-
.withIndex("by_slug", (q) => q.eq("slug", args.slug))
|
|
168
|
-
.collect();
|
|
169
|
-
|
|
170
|
-
return pages
|
|
171
|
-
.filter((p) => p.version)
|
|
172
|
-
.sort((a, b) => (b.version ?? "").localeCompare(a.version ?? ""))
|
|
173
|
-
.map((p) => ({ ...p, id: p._id }));
|
|
174
|
-
},
|
|
175
|
-
});
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { defineSchema, defineTable } from "convex/server";
|
|
2
|
-
import { v } from "convex/values";
|
|
3
|
-
|
|
4
|
-
export default defineSchema({
|
|
5
|
-
doc_sections: defineTable({
|
|
6
|
-
title: v.string(),
|
|
7
|
-
slug: v.string(),
|
|
8
|
-
parentId: v.optional(v.id("doc_sections")),
|
|
9
|
-
order: v.number(),
|
|
10
|
-
icon: v.optional(v.string()),
|
|
11
|
-
description: v.optional(v.string()),
|
|
12
|
-
access: v.union(v.literal("public"), v.literal("team"), v.literal("admin")),
|
|
13
|
-
createdAt: v.number(),
|
|
14
|
-
})
|
|
15
|
-
.index("by_slug", ["slug"])
|
|
16
|
-
.index("by_parentId", ["parentId"])
|
|
17
|
-
.index("by_order", ["order"]),
|
|
18
|
-
|
|
19
|
-
doc_pages: defineTable({
|
|
20
|
-
title: v.string(),
|
|
21
|
-
slug: v.string(),
|
|
22
|
-
content: v.string(),
|
|
23
|
-
excerpt: v.optional(v.string()),
|
|
24
|
-
sectionId: v.id("doc_sections"),
|
|
25
|
-
order: v.number(),
|
|
26
|
-
author: v.object({ name: v.string(), avatar: v.optional(v.string()) }),
|
|
27
|
-
lastEditedBy: v.optional(
|
|
28
|
-
v.object({ name: v.string(), editedAt: v.string() })
|
|
29
|
-
),
|
|
30
|
-
version: v.optional(v.string()),
|
|
31
|
-
access: v.union(v.literal("public"), v.literal("team"), v.literal("admin")),
|
|
32
|
-
tags: v.array(v.string()),
|
|
33
|
-
status: v.union(
|
|
34
|
-
v.literal("draft"),
|
|
35
|
-
v.literal("published"),
|
|
36
|
-
v.literal("archived")
|
|
37
|
-
),
|
|
38
|
-
createdAt: v.number(),
|
|
39
|
-
updatedAt: v.number(),
|
|
40
|
-
wordCount: v.number(),
|
|
41
|
-
readingTime: v.number(),
|
|
42
|
-
viewCount: v.number(),
|
|
43
|
-
})
|
|
44
|
-
.index("by_sectionId", ["sectionId"])
|
|
45
|
-
.index("by_slug", ["slug"])
|
|
46
|
-
.index("by_status", ["status"])
|
|
47
|
-
.index("by_access", ["access"]),
|
|
48
|
-
|
|
49
|
-
doc_search_index: defineTable({
|
|
50
|
-
pageId: v.id("doc_pages"),
|
|
51
|
-
sectionId: v.id("doc_sections"),
|
|
52
|
-
tokens: v.array(v.string()),
|
|
53
|
-
updatedAt: v.number(),
|
|
54
|
-
}).index("by_pageId", ["pageId"]),
|
|
55
|
-
});
|
package/packages/react/README.md
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
# ✦ @geenius-docs/react\n\n> A premium module for the Geenius Boilerplate Ecosystem.\n\n---\n\n## Overview\nBuilt with Steve Jobs-level minimalism and Jony Ive-level craftsmanship, this package is designed to deliver unparalleled developer experience (DX) and rock-solid performance.\n\n## Installation\n\n```bash\npnpm add @geenius-docs/react\n```\n\n## Usage\n\n```typescript\nimport { init } from '@geenius-docs/react';\n\n// Initialize the module with absolute precision\ninit({\n mode: 'premium',\n});\n```\n\n## Architecture\n- **Zero-config**: It just works.\n- **Strictly Typed**: Fully written in TypeScript for flawless IntelliSense.\n- **Framework Agnostic**: seamlessly integrates into the Geenius ecosystem.\n\n---\n\n*Designed by Antigravity HQ*\n
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@geenius-docs/react",
|
|
3
|
-
"version": "0.1.0",
|
|
4
|
-
"type": "module",
|
|
5
|
-
"main": "./src/index.ts",
|
|
6
|
-
"types": "./src/index.ts",
|
|
7
|
-
"exports": {
|
|
8
|
-
".": "./src/index.ts"
|
|
9
|
-
},
|
|
10
|
-
"peerDependencies": {
|
|
11
|
-
"react": ">=18.0.0"
|
|
12
|
-
},
|
|
13
|
-
"dependencies": {
|
|
14
|
-
"@geenius-docs/shared": "workspace:*",
|
|
15
|
-
"lucide-react": "^0.577.0",
|
|
16
|
-
"react-markdown": "^10.1.0",
|
|
17
|
-
"remark-gfm": "^4.0.1"
|
|
18
|
-
},
|
|
19
|
-
"devDependencies": {
|
|
20
|
-
"@tanstack/react-router": "^1.168.1",
|
|
21
|
-
"@types/react": "^19.0.0",
|
|
22
|
-
"@types/react-dom": "^19.0.0",
|
|
23
|
-
"typescript": "~6.0.2"
|
|
24
|
-
},
|
|
25
|
-
"scripts": {
|
|
26
|
-
"type-aml": "tsc --noEmit"
|
|
27
|
-
},
|
|
28
|
-
"author": "Antigravity HQ",
|
|
29
|
-
"license": "MIT",
|
|
30
|
-
"engines": {
|
|
31
|
-
"node": ">=20.0.0"
|
|
32
|
-
},
|
|
33
|
-
"publishConfig": {
|
|
34
|
-
"access": "public"
|
|
35
|
-
}
|
|
36
|
-
}
|
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
import { useDocs } from './DocsProvider'
|
|
3
|
-
|
|
4
|
-
interface DocsLayoutProps {
|
|
5
|
-
children?: React.ReactNode
|
|
6
|
-
currentPageId?: string
|
|
7
|
-
onSelectPage?: (id: string) => void
|
|
8
|
-
searchQuery?: string
|
|
9
|
-
onSearch?: (query: string) => void
|
|
10
|
-
searchResults?: any[]
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* A professional, high-quality layout for Geenius Documentation.
|
|
15
|
-
* Provides a responsive sidebar, searchable navigation, and premium typography.
|
|
16
|
-
*/
|
|
17
|
-
export const DocsLayout: React.FC<DocsLayoutProps> = ({
|
|
18
|
-
children,
|
|
19
|
-
currentPageId,
|
|
20
|
-
onSelectPage,
|
|
21
|
-
searchQuery: searchQueryProp,
|
|
22
|
-
onSearch: onSearchProp,
|
|
23
|
-
searchResults: searchResultsProp
|
|
24
|
-
}) => {
|
|
25
|
-
const {
|
|
26
|
-
tree,
|
|
27
|
-
selectPage,
|
|
28
|
-
setSearchQuery,
|
|
29
|
-
searchQuery: contextSearchQuery,
|
|
30
|
-
searchResults: contextSearchResults
|
|
31
|
-
} = useDocs()
|
|
32
|
-
|
|
33
|
-
const q = searchQueryProp ?? contextSearchQuery
|
|
34
|
-
const results = searchResultsProp ?? contextSearchResults
|
|
35
|
-
const onSelect = onSelectPage ?? selectPage
|
|
36
|
-
const onSearch = onSearchProp ?? setSearchQuery
|
|
37
|
-
|
|
38
|
-
return (
|
|
39
|
-
<div className="flex min-h-[calc(100vh-64px)] bg-background">
|
|
40
|
-
{/* Searchable Sidebar */}
|
|
41
|
-
<aside className="w-80 border-r bg-card/10 backdrop-blur-xl flex flex-col shrink-0 overflow-hidden">
|
|
42
|
-
<div className="p-6 space-y-4">
|
|
43
|
-
<div className="relative group">
|
|
44
|
-
<span className="absolute left-3 top-1/2 -translate-y-1/2 text-muted-foreground transition-colors group-focus-within:text-primary">
|
|
45
|
-
<svg className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5"><circle cx="11" cy="11" r="8"/><path d="m21 21-4.3-4.3"/></svg>
|
|
46
|
-
</span>
|
|
47
|
-
<input
|
|
48
|
-
value={q}
|
|
49
|
-
onChange={(e) => onSearch(e.target.value)}
|
|
50
|
-
placeholder="Search knowledge base..."
|
|
51
|
-
className="w-full pl-10 pr-4 py-2.5 rounded-2xl border bg-background/50 text-sm focus:ring-2 ring-primary/20 outline-none transition-all placeholder:text-muted-foreground/30"
|
|
52
|
-
/>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
|
|
56
|
-
<nav className="flex-1 overflow-y-auto px-4 pb-12 space-y-8 scrollbar-hide">
|
|
57
|
-
{q && results.length > 0 ? (
|
|
58
|
-
<div className="space-y-2 px-2 animate-in fade-in slide-in-from-top-2 duration-300">
|
|
59
|
-
<p className="text-[10px] font-bold text-muted-foreground uppercase tracking-widest mb-4 opacity-50 px-2">
|
|
60
|
-
Search Results ({results.length})
|
|
61
|
-
</p>
|
|
62
|
-
{results.map(page => (
|
|
63
|
-
<button
|
|
64
|
-
key={page.id}
|
|
65
|
-
onClick={() => { onSelect(page.id); onSearch('') }}
|
|
66
|
-
className="w-full p-4 rounded-2xl border bg-card/30 hover:bg-card hover:border-primary/20 hover:shadow-xl hover:shadow-primary/5 text-left transition-all duration-300 group"
|
|
67
|
-
>
|
|
68
|
-
<h5 className="text-sm font-bold group-hover:text-primary transition-colors">{page.title}</h5>
|
|
69
|
-
{page.description && <p className="text-[10px] text-muted-foreground line-clamp-1 mt-1 opacity-70">{page.description}</p>}
|
|
70
|
-
</button>
|
|
71
|
-
))}
|
|
72
|
-
</div>
|
|
73
|
-
) : (
|
|
74
|
-
tree.map(group => (
|
|
75
|
-
<div key={group.id} className="space-y-2">
|
|
76
|
-
<h4 className="px-4 text-[10px] font-bold text-muted-foreground uppercase tracking-widest opacity-40">
|
|
77
|
-
{group.title}
|
|
78
|
-
</h4>
|
|
79
|
-
<div className="space-y-0.5">
|
|
80
|
-
{group.children.map(page => {
|
|
81
|
-
const isActive = page.id === currentPageId
|
|
82
|
-
return (
|
|
83
|
-
<button
|
|
84
|
-
key={page.id}
|
|
85
|
-
onClick={() => onSelect(page.id)}
|
|
86
|
-
className={`w-full flex items-center gap-3 px-4 py-3 rounded-xl text-sm font-medium transition-all group ${isActive ? 'bg-primary/5 text-primary shadow-inner' : 'text-muted-foreground hover:bg-muted/50 hover:text-foreground'}`}
|
|
87
|
-
>
|
|
88
|
-
<span className={`w-1.5 h-1.5 rounded-full transition-all ${isActive ? 'bg-primary scale-125 shadow-[0_0_8px_rgba(var(--primary),0.5)]' : 'bg-transparent group-hover:bg-muted-foreground/20'}`} />
|
|
89
|
-
{page.title}
|
|
90
|
-
</button>
|
|
91
|
-
)
|
|
92
|
-
})}
|
|
93
|
-
</div>
|
|
94
|
-
</div>
|
|
95
|
-
))
|
|
96
|
-
)}
|
|
97
|
-
</nav>
|
|
98
|
-
</aside>
|
|
99
|
-
|
|
100
|
-
{/* Dynamic Content Area */}
|
|
101
|
-
<main className="flex-1 overflow-y-auto overscroll-contain">
|
|
102
|
-
<div className="max-w-4xl mx-auto px-12 py-16 animate-in fade-in slide-in-from-bottom-8 duration-700">
|
|
103
|
-
{children}
|
|
104
|
-
|
|
105
|
-
<div className="mt-20 pt-8 border-t border-dashed flex items-center justify-between opacity-50">
|
|
106
|
-
<p className="text-xs font-medium text-muted-foreground">© 2024 Geenius. Premium Documentation.</p>
|
|
107
|
-
<div className="flex gap-4">
|
|
108
|
-
<button className="text-xs hover:text-primary transition-colors">Edit on GitHub</button>
|
|
109
|
-
<button className="text-xs hover:text-primary transition-colors">Community Help</button>
|
|
110
|
-
</div>
|
|
111
|
-
</div>
|
|
112
|
-
</div>
|
|
113
|
-
</main>
|
|
114
|
-
</div>
|
|
115
|
-
)
|
|
116
|
-
}
|
|
@@ -1,93 +0,0 @@
|
|
|
1
|
-
import React, { createContext, useContext, useState, useMemo, useCallback } from 'react'
|
|
2
|
-
|
|
3
|
-
export interface DocsPage {
|
|
4
|
-
id: string
|
|
5
|
-
title: string
|
|
6
|
-
description?: string
|
|
7
|
-
content: any
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface DocsGroup {
|
|
11
|
-
id: string
|
|
12
|
-
title: string
|
|
13
|
-
children: DocsPage[]
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type DocsTree = DocsGroup[]
|
|
17
|
-
|
|
18
|
-
interface DocsContextValue {
|
|
19
|
-
tree: DocsTree
|
|
20
|
-
currentPage: DocsPage | null
|
|
21
|
-
selectPage: (id: string) => void
|
|
22
|
-
searchQuery: string
|
|
23
|
-
setSearchQuery: (query: string) => void
|
|
24
|
-
searchResults: DocsPage[]
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
const DocsContext = createContext<DocsContextValue | null>(null)
|
|
28
|
-
|
|
29
|
-
interface DocsProviderProps {
|
|
30
|
-
tree: DocsTree
|
|
31
|
-
children: React.ReactNode
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* DocsProvider — Manages documentation state including current page,
|
|
36
|
-
* search, and navigation through the docs tree.
|
|
37
|
-
*/
|
|
38
|
-
export const DocsProvider: React.FC<DocsProviderProps> = ({ tree, children }) => {
|
|
39
|
-
const [currentPageId, setCurrentPageId] = useState<string | null>(tree[0]?.children[0]?.id || null)
|
|
40
|
-
const [searchQuery, setSearchQuery] = useState('')
|
|
41
|
-
|
|
42
|
-
const currentPage = useMemo(() => {
|
|
43
|
-
for (const group of tree) {
|
|
44
|
-
const page = group.children.find(p => p.id === currentPageId)
|
|
45
|
-
if (page) return page
|
|
46
|
-
}
|
|
47
|
-
return null
|
|
48
|
-
}, [tree, currentPageId])
|
|
49
|
-
|
|
50
|
-
const selectPage = useCallback((id: string) => {
|
|
51
|
-
setCurrentPageId(id)
|
|
52
|
-
}, [])
|
|
53
|
-
|
|
54
|
-
const searchResults = useMemo(() => {
|
|
55
|
-
if (!searchQuery) return []
|
|
56
|
-
const results: DocsPage[] = []
|
|
57
|
-
const query = searchQuery.toLowerCase()
|
|
58
|
-
|
|
59
|
-
for (const group of tree) {
|
|
60
|
-
for (const page of group.children) {
|
|
61
|
-
if (
|
|
62
|
-
page.title.toLowerCase().includes(query) ||
|
|
63
|
-
page.description?.toLowerCase().includes(query) ||
|
|
64
|
-
(typeof page.content === 'string' && page.content.toLowerCase().includes(query))
|
|
65
|
-
) {
|
|
66
|
-
results.push(page)
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
return results
|
|
71
|
-
}, [tree, searchQuery])
|
|
72
|
-
|
|
73
|
-
return (
|
|
74
|
-
<DocsContext.Provider value={{
|
|
75
|
-
tree,
|
|
76
|
-
currentPage,
|
|
77
|
-
selectPage,
|
|
78
|
-
searchQuery,
|
|
79
|
-
setSearchQuery,
|
|
80
|
-
searchResults
|
|
81
|
-
}}>
|
|
82
|
-
{children}
|
|
83
|
-
</DocsContext.Provider>
|
|
84
|
-
)
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
export function useDocs() {
|
|
88
|
-
const context = useContext(DocsContext)
|
|
89
|
-
if (!context) {
|
|
90
|
-
throw new Error('useDocs must be used within a DocsProvider')
|
|
91
|
-
}
|
|
92
|
-
return context
|
|
93
|
-
}
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
// src/components/docs/DocsContent.tsx
|
|
2
|
-
|
|
3
|
-
import React from 'react'
|
|
4
|
-
import ReactMarkdown from 'react-markdown'
|
|
5
|
-
import remarkGfm from 'remark-gfm'
|
|
6
|
-
import { Link } from '@tanstack/react-router'
|
|
7
|
-
|
|
8
|
-
interface DocsContentProps {
|
|
9
|
-
content: string
|
|
10
|
-
title: string
|
|
11
|
-
description: string
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export const DocsContent: React.FC<DocsContentProps> = ({
|
|
15
|
-
content,
|
|
16
|
-
title,
|
|
17
|
-
description,
|
|
18
|
-
}) => {
|
|
19
|
-
return (
|
|
20
|
-
<article className="prose prose-lg dark:prose-invert max-w-none">
|
|
21
|
-
{/* Header */}
|
|
22
|
-
<header className="mb-8 pb-8 border-b border-border not-prose">
|
|
23
|
-
<h1 className="text-4xl font-extrabold text-text-main mb-3">{title}</h1>
|
|
24
|
-
<p className="text-lg text-text-muted">{description}</p>
|
|
25
|
-
</header>
|
|
26
|
-
|
|
27
|
-
{/* Markdown Content */}
|
|
28
|
-
<ReactMarkdown
|
|
29
|
-
remarkPlugins={[remarkGfm]}
|
|
30
|
-
components={{
|
|
31
|
-
// Custom heading styles
|
|
32
|
-
h1: ({ children }) => (
|
|
33
|
-
<h1 className="text-3xl font-bold text-text-main mt-12 mb-6">
|
|
34
|
-
{children}
|
|
35
|
-
</h1>
|
|
36
|
-
),
|
|
37
|
-
h2: ({ children }) => (
|
|
38
|
-
<h2 className="text-2xl font-bold text-text-main mt-10 mb-4 pb-2 border-b border-border">
|
|
39
|
-
{children}
|
|
40
|
-
</h2>
|
|
41
|
-
),
|
|
42
|
-
h3: ({ children }) => (
|
|
43
|
-
<h3 className="text-xl font-bold text-text-main mt-8 mb-3">
|
|
44
|
-
{children}
|
|
45
|
-
</h3>
|
|
46
|
-
),
|
|
47
|
-
h4: ({ children }) => (
|
|
48
|
-
<h4 className="text-lg font-semibold text-text-main mt-6 mb-2">
|
|
49
|
-
{children}
|
|
50
|
-
</h4>
|
|
51
|
-
),
|
|
52
|
-
// Paragraph
|
|
53
|
-
p: ({ children }) => (
|
|
54
|
-
<p className="text-text-muted leading-relaxed mb-4">{children}</p>
|
|
55
|
-
),
|
|
56
|
-
// Links
|
|
57
|
-
a: ({ href, children }) => {
|
|
58
|
-
const isInternal = href?.startsWith('/')
|
|
59
|
-
if (isInternal) {
|
|
60
|
-
return (
|
|
61
|
-
<Link
|
|
62
|
-
to={href!}
|
|
63
|
-
className="text-primary hover:underline font-medium"
|
|
64
|
-
>
|
|
65
|
-
{children}
|
|
66
|
-
</Link>
|
|
67
|
-
)
|
|
68
|
-
}
|
|
69
|
-
return (
|
|
70
|
-
<a
|
|
71
|
-
href={href}
|
|
72
|
-
target="_blank"
|
|
73
|
-
rel="noopener noreferrer"
|
|
74
|
-
className="text-primary hover:underline font-medium"
|
|
75
|
-
>
|
|
76
|
-
{children}
|
|
77
|
-
</a>
|
|
78
|
-
)
|
|
79
|
-
},
|
|
80
|
-
// Code blocks
|
|
81
|
-
code: ({ className, children, ...props }) => {
|
|
82
|
-
const isInline = !className
|
|
83
|
-
if (isInline) {
|
|
84
|
-
return (
|
|
85
|
-
<code className="bg-bg-muted px-1.5 py-0.5 rounded text-sm font-mono text-primary">
|
|
86
|
-
{children}
|
|
87
|
-
</code>
|
|
88
|
-
)
|
|
89
|
-
}
|
|
90
|
-
return (
|
|
91
|
-
<code className={`${className} block`} {...props}>
|
|
92
|
-
{children}
|
|
93
|
-
</code>
|
|
94
|
-
)
|
|
95
|
-
},
|
|
96
|
-
pre: ({ children }) => (
|
|
97
|
-
<pre className="bg-[#1e1e2e] text-gray-100 p-4 rounded-xl overflow-x-auto text-sm my-6 border border-border">
|
|
98
|
-
{children}
|
|
99
|
-
</pre>
|
|
100
|
-
),
|
|
101
|
-
// Lists
|
|
102
|
-
ul: ({ children }) => (
|
|
103
|
-
<ul className="list-disc list-inside space-y-2 text-text-muted mb-4">
|
|
104
|
-
{children}
|
|
105
|
-
</ul>
|
|
106
|
-
),
|
|
107
|
-
ol: ({ children }) => (
|
|
108
|
-
<ol className="list-decimal list-inside space-y-2 text-text-muted mb-4">
|
|
109
|
-
{children}
|
|
110
|
-
</ol>
|
|
111
|
-
),
|
|
112
|
-
li: ({ children }) => <li className="text-text-muted">{children}</li>,
|
|
113
|
-
// Tables
|
|
114
|
-
table: ({ children }) => (
|
|
115
|
-
<div className="overflow-x-auto my-6">
|
|
116
|
-
<table className="min-w-full divide-y divide-border border border-border rounded-lg overflow-hidden">
|
|
117
|
-
{children}
|
|
118
|
-
</table>
|
|
119
|
-
</div>
|
|
120
|
-
),
|
|
121
|
-
thead: ({ children }) => (
|
|
122
|
-
<thead className="bg-bg-muted">{children}</thead>
|
|
123
|
-
),
|
|
124
|
-
th: ({ children }) => (
|
|
125
|
-
<th className="px-4 py-3 text-left text-sm font-bold text-text-main">
|
|
126
|
-
{children}
|
|
127
|
-
</th>
|
|
128
|
-
),
|
|
129
|
-
td: ({ children }) => (
|
|
130
|
-
<td className="px-4 py-3 text-sm text-text-muted border-t border-border">
|
|
131
|
-
{children}
|
|
132
|
-
</td>
|
|
133
|
-
),
|
|
134
|
-
// Blockquotes
|
|
135
|
-
blockquote: ({ children }) => (
|
|
136
|
-
<blockquote className="border-l-4 border-primary pl-4 py-2 my-6 bg-primary/5 rounded-r-lg">
|
|
137
|
-
{children}
|
|
138
|
-
</blockquote>
|
|
139
|
-
),
|
|
140
|
-
// Horizontal rules
|
|
141
|
-
hr: () => <hr className="border-border my-8" />,
|
|
142
|
-
}}
|
|
143
|
-
>
|
|
144
|
-
{content}
|
|
145
|
-
</ReactMarkdown>
|
|
146
|
-
</article>
|
|
147
|
-
)
|
|
148
|
-
}
|