commit ea9a71e23c850d2dd2922ec99ecabeeff460a2b5 Author: Wildan Nursahidan Date: Sat Apr 12 14:34:53 2025 +0700 initial docs diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..bffb357 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,3 @@ +{ + "extends": "next/core-web-vitals" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fd3dbb5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc +.DS_Store +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/.vscode/accordion.code-snippets b/.vscode/accordion.code-snippets new file mode 100644 index 0000000..efb3a05 --- /dev/null +++ b/.vscode/accordion.code-snippets @@ -0,0 +1,14 @@ +{ + "DocuAccordion": { + "prefix": "accordion", + "body": [ + "", + " this is an example of plain text content from the accordion component and below is markdown ;", + " 1. number one", + " 2. number two", + " 3. number three", + "" + ], + "description": "Create a DocuAccordion component with markdown list." + } + } diff --git a/.vscode/button.code-snippets b/.vscode/button.code-snippets new file mode 100644 index 0000000..3142994 --- /dev/null +++ b/.vscode/button.code-snippets @@ -0,0 +1,16 @@ +{ + "DocuButton": { + "prefix": "button", + "body": [ + "" + ], + "description": "Create a DocuButton component on markdown." + } + } diff --git a/.vscode/card.code-snippets b/.vscode/card.code-snippets new file mode 100644 index 0000000..02af419 --- /dev/null +++ b/.vscode/card.code-snippets @@ -0,0 +1,16 @@ +{ + "DocuCards": { + "prefix": "card", + "body": [ + "", + "", + " This is an example of card content with columns.", + "", + "", + " This is an example of card content with columns.", + "", + "" + ], + "description": "Create a DocuCards component on markdown." + } + } diff --git a/.vscode/codeblock.code-snippets b/.vscode/codeblock.code-snippets new file mode 100644 index 0000000..ec5d1a1 --- /dev/null +++ b/.vscode/codeblock.code-snippets @@ -0,0 +1,16 @@ +{ + "DocuCodeBlock": { + "prefix": "codeblock", + "description": "Checks if the rocket is stable and prevents a crash if it's not.", + "body": [ + "```${1:javascript:main.js} showLineNumbers {${2:3-4}}", + "function isRocketAboutToCrash() {", + " // Check if the rocket is stable", + " if (!isStable()) {", + " NoCrash(); // Prevent the crash", + " }", + "}", + "```", + ], + } +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..4ef01b0 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": [] +} diff --git a/.vscode/image-link.code-snippets b/.vscode/image-link.code-snippets new file mode 100644 index 0000000..b4a86c5 --- /dev/null +++ b/.vscode/image-link.code-snippets @@ -0,0 +1,16 @@ +{ + "DocuImage": { + "prefix": "image", + "body": [ + "![${1:Alt text for the image}](${2:https://via.placeholder.com/150})" + ], + "description": "Snippet untuk menampilkan image komponen." + }, + "DocuLink": { + "prefix": "link", + "body": [ + "[${1:Text Link}](${2:https://www.openai.com})" + ], + "description": "Snippet untuk menampilkan link komponen." + } +} diff --git a/.vscode/metadata.code-snippets b/.vscode/metadata.code-snippets new file mode 100644 index 0000000..5cd7ce9 --- /dev/null +++ b/.vscode/metadata.code-snippets @@ -0,0 +1,13 @@ +{ + "DocuMetadata": { + "prefix": "metadata", + "body": [ + "---", + "title : ${1:judul post}", + "description : ${2:deskripsi singkat dari post}", + "date : ${3:10-12-2024}", + "---" + ], + "description": "Snippet untuk membuat metadata." + } +} diff --git a/.vscode/note.code-snippets b/.vscode/note.code-snippets new file mode 100644 index 0000000..0126504 --- /dev/null +++ b/.vscode/note.code-snippets @@ -0,0 +1,38 @@ +{ + "DocuNote - General Note": { + "prefix": "note", + "body": [ + "", + " ${1:This is a general note to convey information to the user.}", + "" + ], + "description": "Insert a general note" + }, + "DocuNote - Danger Note": { + "prefix": "danger", + "body": [ + "", + " ${1:This is a danger alert to notify the user of a critical issue.}", + "" + ], + "description": "Insert a danger note" + }, + "DocuNote - Warning Note": { + "prefix": "warning", + "body": [ + "", + " ${1:This is a warning alert for issues that require attention.}", + "" + ], + "description": "Insert a warning note" + }, + "DocuNote - Success Note": { + "prefix": "success", + "body": [ + "", + " ${1:This is a success message to inform the user of successful actions.}", + "" + ], + "description": "Insert a success note" + } +} diff --git a/.vscode/stepper.code-snippets b/.vscode/stepper.code-snippets new file mode 100644 index 0000000..704d492 --- /dev/null +++ b/.vscode/stepper.code-snippets @@ -0,0 +1,24 @@ +{ + "DocuStepper": { + "prefix": "stepper", + "body": [ + "", + " ", + " Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec interdum,", + " felis sed efficitur tincidunt, justo nulla viverra enim, et maximus nunc", + " dolor in lorem.", + " ${2:}", + "" + ], + "description": "Snippet untuk menampilkan stepper komponen." + }, + "DocuStepperItem": { + "prefix": "item", + "body": [ + "", + " ${2:Your step description here.}", + "${3:}" + ], + "description": "Snippet untuk menambahkan item baru ke dalam Stepper." + } +} diff --git a/.vscode/table.code-snippets b/.vscode/table.code-snippets new file mode 100644 index 0000000..202f150 --- /dev/null +++ b/.vscode/table.code-snippets @@ -0,0 +1,20 @@ +{ + "DocuTable": { + "prefix": "table", + "body": [ + "| **${1:Feature}** | **${2:Description}** |", + "| ------------------------------- | ----------------------------------------------------- |", + "| ${3:MDX Support} | ${4:Write interactive documentation with MDX.} |", + "| Nested Pages | Organize content in a nested, hierarchical structure. |", + "| Blog Section | Include a dedicated blog section. |", + "| Pagination | Split content across multiple pages. |", + "| Syntax Highlighting | Highlight code for better readability. |", + "| Code Line Highlighting & Titles | Highlight specific lines with descriptive titles. |", + "| Interactive Code Blocks | Language-specific and interactive code display. |", + "| Custom Markdown Components | Embed custom, reusable components in your docs. |", + "| Static Site Generation | Generate a static, high-performance site. |", + "| SEO-Optimized | Structured for optimal search engine indexing. |" + ], + "description": "Create a DocuTable component on markdown." + } + } diff --git a/.vscode/tabs.code-snippets b/.vscode/tabs.code-snippets new file mode 100644 index 0000000..02e2f36 --- /dev/null +++ b/.vscode/tabs.code-snippets @@ -0,0 +1,33 @@ +{ + "DocuTabs": { + "prefix": "tabs", + "body": [ + "", + " ", + " Java", + " TypeScript", + " ", + " ", + " ```java", + " // HelloWorld.java", + " public class HelloWorld {", + " public static void main(String[] args) {", + " System.out.println(\"Hello, World!\");", + " }", + " }", + " ```", + " ", + " ", + " ```typescript", + " // helloWorld.ts", + " function helloWorld(): void {", + " console.log(\"Hello, World!\");", + " }", + " helloWorld();", + " ```", + " ", + "" + ], + "description": "Create a DocuTabs component with Java and TypeScript examples." + } + } diff --git a/.vscode/tooltips.code-snippets b/.vscode/tooltips.code-snippets new file mode 100644 index 0000000..9299451 --- /dev/null +++ b/.vscode/tooltips.code-snippets @@ -0,0 +1,9 @@ +{ + "DocuTooltips": { + "prefix": "tooltips", + "body": [ + "${1:What do you know about } ${4:? Create interactive nested documentations using MDX.}", + ], + "description": "Create a DocuTooltips component with version examples." + } + } diff --git a/.vscode/typography.code-snippets b/.vscode/typography.code-snippets new file mode 100644 index 0000000..d534da3 --- /dev/null +++ b/.vscode/typography.code-snippets @@ -0,0 +1,33 @@ +{ + "DocuH2": { + "prefix": "h2", + "body": [ + "## Heading 2" + ], + "description": "Tag Heading 2 for markdown." + }, + "DocuH3": { + "prefix": "h3", + "body": [ + "### Heading 3" + ], + "description": "Tag Heading 3 for markdown." + }, + "DocuText": { + "prefix": "text", + "body": [ + "DocuBook is proudly **open-source**! 🎉 We believe in creating an accessible, collaborative platform that thrives on community contributions." + ], + "description": "Tag Paragraph for markdown." + }, + "Docu-UndorderList": { + "prefix": "unorderlist", + "body": [ + "- ${1:**Next.js 14** - The powerful React framework optimized for production.}", + "- **Tailwind CSS** - Utility-first styling for quick, clean designs.", + "- **Shadcn-UI** - Elegant, accessible components for a polished look.", + "- **next-mdx-remote** - Enables MDX support for dynamic, interactive Markdown content." + ], + "description": "Tag Undorderlist for markdown." + }, +} diff --git a/.vscode/youtube.code-snippets b/.vscode/youtube.code-snippets new file mode 100644 index 0000000..6ec60a4 --- /dev/null +++ b/.vscode/youtube.code-snippets @@ -0,0 +1,9 @@ +{ + "DocuVideo": { + "prefix": "youtube", + "body": [ + "" + ], + "description": "Snippet untuk menampilkan komponen video Youtube." + } +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..0cac9ce --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,329 @@ +## [1.8.0] - 2025-03-01 + +> Now looks more modern and clean which is a big change in layout and design + +### Added + +- Social footer +- Toggle group +- Site description {meta.description} in footer +- Site title {meta.title} in footer + +### Improved + +- Header design changes +- Footer design changes +- New functions in theme provider +- Object changes in docu.json + +### Fixed + +- Updates to path structure components +- Groups to organize components + +## [1.7.0] - 2025-02-23 + +> Remove the old function in the search dialog and replace it with a new and more optimal feature + +### Added + +- Up and down navigation : search dialog.tsx +- Enter (return) to select : search dialog.tsx +- Escape to close the dialog : search dialog.tsx + +### Improved + +- Maintenance for anchor components +- Anchor.tsx adjustments for all elements that use it + +### Removed + +- Remove suboptimal search features + +## [1.6.0] - 2025-02-21 + +> New Feature Card Groups with arrays for more Flexible Content + +### Added + +- Card Groups Components +- Props : href to url link +- Props : horizontal boolean + +### Improved + +- Card props styling +- Compability for Cards components +- {children} support for card content + +### Removed + +- remove unused props cards components + +## [1.5.0] - 2025-02-18 + +> Minor Update - improved features and responsiveness on all devices + +### Added + +- New dialog footer on searchbox above @media 768px +- Icon X for close dialog on searcbox as esc on medium screen + +### Improved + +- Responsive Leftbar components on large screen +- Menu Trigger on medium screen +- Responsive Navbar components on medium screen +- Better UX for searchbox dialog +- tooltips components can be written together with regular paragraphs + +### Fixed + +- Responsive issue +- Compatibility for Bun +- Changes postcss.config.js to .cjs for Bun +- all CLI installer and updater not working +- adjustments for package managers npm, pnpm, bun, yarn + +## [1.4.2] - 2025-02-16 + +> Complex Content for Accordion Component props {children} + +### Added + +- New Props with {children} in accordion +- Compatibility for markdown in accordion +- Nested components inside an accordion +- New icon on note components +- add CLI npx @docubook/create@latest +- add CLI npx @docubook/update@latest + +### Improved + +- Better UI design for accordion +- Styling Note components on markdown +- Change accordion output on playground +- Change accordion output on snippet + +### Removed + +- Remove depcreated props on accordion +- Remove CLI npx update_docu +- Remove CLI npx create_docu + +## [1.4.0] - 2025-02-11 + +> Floating Button Version with Dynamic Tag {version} on Changelog page + +### Added + +- New components / changelog floating-version.tsx +- Button popover to open version-toc below @media 1024px +- Dynamic tag by section ID #version +- Dynamic url tag #version +- Dynamic version indicator on floating version when scrolling section by ID + +### Improved + +- change icon version history +- responsive version-toc +- improvement components to changelog page + +## [1.3.8] - 2025-02-08 + +> Responsive Table of Content + +### Added + +- Components terminal MagicUI +- Components card Shadcn +- New mob-toc for a better experience on mobile devices +- New Components scroll to top button +- Scroll to top :blog-post +- Scroll to top :docs-post + +### Improved + +- lib/markdown for generated dynamic toc on markdown +- Responsive Table of Content below @media 1024px +- Improve docs page + +## [1.3.6] - 2025-02-01 + +> Appears more modern editor for Docu Play + +![version 1.3.6 - Playground](https://docubook.pro/images/new-editor.png) + +### Added + +- Line Number for editor +- editor.css + +### Improved + +- Better Design for Editor +- Similar to Github Editor +- Moved Handler Element (copy, download, reset and fullscreen) on Header + +## [1.3.5] - 2025-01-30 + +> it's Easy to Write Markdown with Playground + +![version 1.3.5 - Playground](https://docubook.pro/images/img-playground.png) + +### Added + +- New Playground Page +- New Playground Layout +- Toolbar for Markdown Components +- Fullscreen Mode to Focus Editing Your Content +- Copy to Clipboard Your Content +- Download Your Content as index.mdx +- Reset Your Content without refresh the Browser +- Only Large Screen for Better Experience + +## [1.3.1] - 2025-01-20 + +> Snippet Feature to Easily Write Markdown and Call DocuBook Components + +![version 1.3.1 - Snippet Features](https://docubook.pro/images/snippet.png) + +### Added + +- New Feature Snippet for Markdown Components +- Support Snippet for Visual Studio Code + +### Removed + +- remove props icon and props description for accordion components + +## [1.3.0] - 2024-12-31 + +> Release Note Feature to Make it Easier to Write Changelogs + +### Added + +- New Release Note Feature +- New Layout for Changelog page +- New Changelog page +- Add Release Note Component +- Easily write release notes directly from the CHANGELOG.md file +- TOC for versioning +- Write with the markdown tag +- Add lib / changelog.ts + +### Improved + +- Improvement Responsive feature image for Version Entry +- Improvement Layout for changelog page +- Improvement Padding on mobile devices +- Only use containers of md size +- Improvement syntax.css for ul>li classes + +### Fixed + +- Fix og:image not showing on Page.tsx +- Fix text-indent on class li + +### Removed + +- Remove excessive padding +- Remove Logo on Footer + +## [1.2.0] - 2024-12-22 + +> New Accordion Component : Support content plain text, html and all markdown component + +### Added + +- add New Accordion + +### Improved + +- Props Improvement +- Support Dynamic Content for Accordion + +## [1.1.0] - 2024-12-15 + +> Minor Update : Easily manage set up with docu.json + +### Added + +- add docu.json file +- add openGraph (title, description, image) +- add Dynamic metadata +- Generate metadata as openGraph +- openGraph support for .mdx + +### Improved + +- routes-config from json +- Frontmatter improvement +- Edit the content of footer.tsx simply via the docu.json file +- Edit the content of navbar.tsx simply via the docu.json file + +## [1.0.7] - 2024-12-14 + +> Easily updates your DocuBook Version with CLI npx update_docu + +### Added + +- CLI npx update_docu (update features into docubook existing directory) +- Playground (easily to written content) +- New Button component +- Navbar external link conditions +- CLI npx create_docu + +### Improved + +- Searchbar Improvement +- Navigation Improvement +- Edit on Github Improvement + +### Removed +- Remove CLI npx create-docu (on this version not usage dash `-`) + +## [1.0.6] - 2024-11-24 + +> New Components, Fix and Improvement + +### Added + +- New Card component +- New Tooltips component + +### Fixed + +- change root folder + +### Improved + +- logo on navbar & footer +- easily change logo + +## [1.0.5] - 2024-11-16 + +> Add New Features and Improvement for this version + +### Added + +- New Youtube component +- edit this page - easily manage directory content via the github repo +- support installation via cli commant npx create-docu + +### Improved + +- keyboard shortcut command + k or ctrl + k to open search dialog + +## [1.0.0] - 2024-11-10 + +> Initial release of DocuBook to create interactive nested docs with MDX + +### Added + +- Initial release of DocuBook +- Basic documentation structure +- Markdown support with MDX +- Responsive design +- Search functionality +- Dark mode support diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..02e35d7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Wildan Nursahidan + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..8d684d2 --- /dev/null +++ b/README.md @@ -0,0 +1,38 @@ +# DocuBook + +**DocuBook** is a documentation web project designed to provide a simple and user-friendly interface for accessing various types of documentation. This site is crafted for developers and teams who need quick access to references, guides, and essential documents. + +> **Note**: This application is a fork of [AriaDocs](https://github.com/nisabmohd/Aria-Docs), created by [Nisab Mohd](https://github.com/nisabmohd). DocuBook provides an alternative to the documentation solution found on [Mintlify](https://mintlify.com/), utilizing `.mdx` (Markdown + JSX) for content creation and management. + +[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/import/project?template=https://github.com/mywildancloud/docubook) + +## Features + +- **Easy Navigation**: Simple layout for quick navigation between pages. +- **Quick Search**: Easily find documentation using a search function. +- **Responsive Theme**: Responsive design optimized for devices ranging from desktops to mobile. +- **Markdown Content**: Support for markdown-based documents. +- **SEO Friendly**: Optimized structure for search visibility, enhancing accessibility on search engines. + +## Installation + +```bash +npx @docubook/create@latest +``` + +#### command output + +```bash +? Enter a name for your project directory: (docubook) + +Creating a new Docubook project in /path/your/docubook from the main branch... +✔ Docubook project successfully created in /path/your/docubook! + +Next steps: +1. Navigate to your project directory: + cd docubook +2. Install dependencies: + npm install +3. Start the development server: + npm run dev +``` diff --git a/app/blog/[slug]/page.tsx b/app/blog/[slug]/page.tsx new file mode 100644 index 0000000..61f6953 --- /dev/null +++ b/app/blog/[slug]/page.tsx @@ -0,0 +1,92 @@ +import { Typography } from "@/components/docs/typography"; +import { buttonVariants } from "@/components/ui/button"; +import { Author, getAllBlogStaticPaths, getBlogForSlug } from "@/lib/markdown"; +import { ArrowLeftIcon } from "lucide-react"; +import Link from "next/link"; +import { notFound } from "next/navigation"; +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { formatDate } from "@/lib/utils"; +import { ScrollToTop } from "@/components/docs/scroll-to-top"; + +type PageProps = { + params: { slug: string }; +}; + +export async function generateMetadata({ params: { slug } }: PageProps) { + const res = await getBlogForSlug(slug); + if (!res) return null; + const { frontmatter } = res; + return { + title: frontmatter.title, + description: frontmatter.description, + }; +} + +export async function generateStaticParams() { + const val = await getAllBlogStaticPaths(); + if (!val) return []; + return val.map((it) => ({ slug: it })); +} + +export default async function BlogPage({ params: { slug } }: PageProps) { + const res = await getBlogForSlug(slug); + if (!res) notFound(); + return ( +
+ + Back to blog + +
+

+ {formatDate(res.frontmatter.date)} +

+

+ {res.frontmatter.title} +

+
+

Posted by

+ +
+
+
+ {res.content} +
+ +
+ ); +} + +function Authors({ authors }: { authors: Author[] }) { + return ( +
+ {authors.map((author) => { + return ( + + + + + {author.username.slice(0, 2).toUpperCase()} + + +
+

{author.username}

+

+ @{author.handle} +

+
+ + ); + })} +
+ ); +} diff --git a/app/blog/layout.tsx b/app/blog/layout.tsx new file mode 100644 index 0000000..6211155 --- /dev/null +++ b/app/blog/layout.tsx @@ -0,0 +1,9 @@ +import { PropsWithChildren } from "react"; + +export default function BlogLayout({ children }: PropsWithChildren) { + return ( +
+ {children} +
+ ); +} diff --git a/app/blog/page.tsx b/app/blog/page.tsx new file mode 100644 index 0000000..dd5eaec --- /dev/null +++ b/app/blog/page.tsx @@ -0,0 +1,98 @@ +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Author, BlogMdxFrontmatter, getAllBlogs } from "@/lib/markdown"; +import { formatDate2, stringToDate } from "@/lib/utils"; +import { getMetadata } from "@/app/layout"; +import Image from "next/image"; +import Link from "next/link"; +import docuConfig from "@/docu.json"; + +export const metadata = getMetadata({ + title: "Blog", + description: "Discover the latest updates, tutorials, and insights on DocuBook.", +}); +const { meta } = docuConfig; +export default async function BlogIndexPage() { + const blogs = (await getAllBlogs()).sort( + (a, b) => stringToDate(b.date).getTime() - stringToDate(a.date).getTime() + ); + return ( +
+
+

+ Blog Posts +

+

+ Discover the latest updates, tutorials, and insights on {meta.title}. +

+
+
+ {blogs.map((blog) => ( + + ))} +
+
+ ); +} + +function BlogCard({ + date, + title, + description, + slug, + cover, + authors, +}: BlogMdxFrontmatter & { slug: string }) { + return ( + +

{title}

+
+ {title} +
+

{description}

+
+

+ Published on {formatDate2(date)} +

+ +
+ + ); +} + +function AvatarGroup({ users, max = 4 }: { users: Author[]; max?: number }) { + const displayUsers = users.slice(0, max); + const remainingUsers = Math.max(users.length - max, 0); + + return ( +
+ {displayUsers.map((user, index) => ( + + + + {user.username.slice(0, 2).toUpperCase()} + + + ))} + {remainingUsers > 0 && ( + + +{remainingUsers} + + )} +
+ ); +} diff --git a/app/changelog/layout.tsx b/app/changelog/layout.tsx new file mode 100644 index 0000000..b77f34a --- /dev/null +++ b/app/changelog/layout.tsx @@ -0,0 +1,11 @@ +export default function ChangelogLayout({ + children, +}: { + children: React.ReactNode; +}) { + return ( +
+ {children} +
+ ); +} \ No newline at end of file diff --git a/app/changelog/page.tsx b/app/changelog/page.tsx new file mode 100644 index 0000000..397a039 --- /dev/null +++ b/app/changelog/page.tsx @@ -0,0 +1,63 @@ +import { Suspense } from "react"; +import { getChangelogEntries } from "@/lib/changelog"; +import { VersionEntry } from "@/components/changelog/version-entry"; +import { VersionToc } from "@/components/changelog/version-toc"; +import { getMetadata } from "@/app/layout"; +import docuConfig from "@/docu.json"; +import { FloatingVersionToc } from "@/components/changelog/floating-version"; + +export const metadata = getMetadata({ + title: "Changelog", + description: "Latest updates and improvements to DocuBook", + image: "release-note.png", +}); + +export default async function ChangelogPage() { + const entries = await getChangelogEntries(); + const { meta } = docuConfig; + return ( +
+
+
+

Changelog

+

+ Latest updates and improvements to {meta.title} +

+
+
+ +
+
+ }> + ({ version, date }))} + /> + + +
+
+
+
+ {entries.map((entry, index) => ( +
+ +
+ ))} +
+
+
+
+
+ {/* Floating TOC for smaller screens */} + {entries.length > 0 && ( + ({ version, date }))} + /> + )} +
+ ); +} diff --git a/app/docs/[[...slug]]/page.tsx b/app/docs/[[...slug]]/page.tsx new file mode 100644 index 0000000..2b0825e --- /dev/null +++ b/app/docs/[[...slug]]/page.tsx @@ -0,0 +1,105 @@ +import { notFound } from "next/navigation"; +import { getDocsForSlug, getDocsTocs } from "@/lib/markdown"; +import DocsBreadcrumb from "@/components/docs/docs-breadcrumb"; +import Pagination from "@/components/docs/pagination"; +import Toc from "@/components/docs/toc"; +import { Typography } from "@/components/docs/typography"; +import EditThisPage from "@/components/docs/edit-on-github"; +import { formatDate2 } from "@/lib/utils"; +import docuConfig from "@/docu.json"; +import MobToc from "@/components/docs/mob-toc"; +import { ScrollToTop } from "@/components/docs/scroll-to-top"; + +const { meta } = docuConfig; + +type PageProps = { + params: { + slug: string[]; + }; +}; + +// Function to generate metadata dynamically +export async function generateMetadata({ params: { slug = [] } }: PageProps) { + const pathName = slug.join("/"); + const res = await getDocsForSlug(pathName); + + if (!res) { + return { + title: "Page Not Found", + description: "The requested page was not found.", + }; + } + + const { title, description, image } = res.frontmatter; + + // Absolute URL for og:image + const ogImage = image + ? `${meta.baseURL}/images/${image}` + : `${meta.baseURL}/images/og-image.png`; + + return { + title: `${title}`, + description, + openGraph: { + title, + description, + url: `${meta.baseURL}/docs/${pathName}`, + type: "article", + images: [ + { + url: ogImage, + width: 1200, + height: 630, + alt: title, + }, + ], + }, + twitter: { + card: "summary_large_image", + title, + description, + images: [ogImage], + }, + }; +} + +export default async function DocsPage({ params: { slug = [] } }: PageProps) { + const pathName = slug.join("/"); + const res = await getDocsForSlug(pathName); + + if (!res) notFound(); + + const { title, description, image, date } = res.frontmatter; + + // File path for edit link + const filePath = `contents/docs/${slug.join("/") || ""}/index.mdx`; + + const tocs = await getDocsTocs(pathName); + + return ( +
+
+ +
+ +
+ +

{title}

+

{description}

+
{res.content}
+
+ {date && ( +

+ Published on {formatDate2(date)} +

+ )} + +
+ +
+ +
+ +
+ ); +} diff --git a/app/docs/layout.tsx b/app/docs/layout.tsx new file mode 100644 index 0000000..c769f8f --- /dev/null +++ b/app/docs/layout.tsx @@ -0,0 +1,14 @@ +import { Leftbar } from "@/components/docs/leftbar"; + +export default function DocsLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( +
+ +
{children}
+
+ ); +} diff --git a/app/error.tsx b/app/error.tsx new file mode 100644 index 0000000..8a8ae0b --- /dev/null +++ b/app/error.tsx @@ -0,0 +1,44 @@ +"use client"; // Error components must be Client Components + +import { Button, buttonVariants } from "@/components/ui/button"; +import Link from "next/link"; +import { useEffect } from "react"; + +export default function Error({ + error, + reset, +}: { + error: Error & { digest?: string }; + reset: () => void; +}) { + useEffect(() => { + console.error(error); + }, [error]); + + return ( +
+
+

Oops!

+

+ Something went wrong {":`("} +

+

+ We're sorry, but an error occurred while processing your request. +

+
+
+ + + Back to homepage + +
+
+ ); +} diff --git a/app/hire-me/page.tsx b/app/hire-me/page.tsx new file mode 100644 index 0000000..327d889 --- /dev/null +++ b/app/hire-me/page.tsx @@ -0,0 +1,18 @@ +import { getMetadata } from "@/app/layout"; + +export const metadata = getMetadata({ + title: "Hire Me", + description: "Hire me to start a documentation project with DocuBook", +}); + +export default function EmbeddedHTML() { + return ( +
+ +
+ ); +}; + +export default Youtube; diff --git a/components/ui/accordion.tsx b/components/ui/accordion.tsx new file mode 100644 index 0000000..24c788c --- /dev/null +++ b/components/ui/accordion.tsx @@ -0,0 +1,58 @@ +"use client" + +import * as React from "react" +import * as AccordionPrimitive from "@radix-ui/react-accordion" +import { ChevronDown } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Accordion = AccordionPrimitive.Root + +const AccordionItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AccordionItem.displayName = "AccordionItem" + +const AccordionTrigger = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + + svg]:rotate-180", + className + )} + {...props} + > + {children} + + + +)) +AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName + +const AccordionContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, children, ...props }, ref) => ( + +
{children}
+
+)) + +AccordionContent.displayName = AccordionPrimitive.Content.displayName + +export { Accordion, AccordionItem, AccordionTrigger, AccordionContent } diff --git a/components/ui/animated-shiny-text.tsx b/components/ui/animated-shiny-text.tsx new file mode 100644 index 0000000..f55fd20 --- /dev/null +++ b/components/ui/animated-shiny-text.tsx @@ -0,0 +1,40 @@ +import { CSSProperties, FC, ReactNode } from "react"; + +import { cn } from "@/lib/utils"; + +interface AnimatedShinyTextProps { + children: ReactNode; + className?: string; + shimmerWidth?: number; +} + +const AnimatedShinyText: FC = ({ + children, + className, + shimmerWidth = 100, +}) => { + return ( +

+ {children} +

+ ); +}; + +export default AnimatedShinyText; diff --git a/components/ui/avatar.tsx b/components/ui/avatar.tsx new file mode 100644 index 0000000..51e507b --- /dev/null +++ b/components/ui/avatar.tsx @@ -0,0 +1,50 @@ +"use client" + +import * as React from "react" +import * as AvatarPrimitive from "@radix-ui/react-avatar" + +import { cn } from "@/lib/utils" + +const Avatar = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +Avatar.displayName = AvatarPrimitive.Root.displayName + +const AvatarImage = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarImage.displayName = AvatarPrimitive.Image.displayName + +const AvatarFallback = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + +)) +AvatarFallback.displayName = AvatarPrimitive.Fallback.displayName + +export { Avatar, AvatarImage, AvatarFallback } diff --git a/components/ui/badge.tsx b/components/ui/badge.tsx new file mode 100644 index 0000000..760ec38 --- /dev/null +++ b/components/ui/badge.tsx @@ -0,0 +1,37 @@ +"use client"; + +import * as React from "react"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "@/lib/utils"; + +const badgeVariants = cva( + "inline-flex items-center rounded-full border px-2.5 py-0.5 text-xs font-semibold transition-colors focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2", + { + variants: { + variant: { + default: + "border-transparent bg-primary text-primary-foreground hover:bg-primary/80", + secondary: + "border-transparent bg-secondary text-secondary-foreground hover:bg-secondary/80", + destructive: + "border-transparent bg-destructive text-destructive-foreground hover:bg-destructive/80", + outline: "text-foreground", + }, + }, + defaultVariants: { + variant: "default", + }, + } +); + +export interface BadgeProps + extends React.HTMLAttributes, + VariantProps {} + +function Badge({ className, variant, ...props }: BadgeProps) { + return ( +
+ ); +} + +export { Badge, badgeVariants }; \ No newline at end of file diff --git a/components/ui/breadcrumb.tsx b/components/ui/breadcrumb.tsx new file mode 100644 index 0000000..71a5c32 --- /dev/null +++ b/components/ui/breadcrumb.tsx @@ -0,0 +1,115 @@ +import * as React from "react" +import { Slot } from "@radix-ui/react-slot" +import { ChevronRight, MoreHorizontal } from "lucide-react" + +import { cn } from "@/lib/utils" + +const Breadcrumb = React.forwardRef< + HTMLElement, + React.ComponentPropsWithoutRef<"nav"> & { + separator?: React.ReactNode + } +>(({ ...props }, ref) =>