mirror of
https://github.com/FranP-code/create-better-t-stack.git
synced 2025-10-12 23:52:15 +00:00
begin docs (#167)
This commit is contained in:
39
apps/web/components/features.tsx
Normal file
39
apps/web/components/features.tsx
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
import { Cards, Card } from "fumadocs-ui/components/card";
|
||||||
|
import { Database, Package, Lock, Globe, Server, Cable } from "lucide-react";
|
||||||
|
|
||||||
|
export default function Features() {
|
||||||
|
return (
|
||||||
|
<Cards>
|
||||||
|
<Card
|
||||||
|
icon={<Globe />}
|
||||||
|
title='Frontend'
|
||||||
|
description='Choose between Tanstack Router, React Router, Expo, Next.js, and more'
|
||||||
|
/>
|
||||||
|
<Card
|
||||||
|
icon={<Server />}
|
||||||
|
title='Flexible Backend'
|
||||||
|
description='Choose between Hono, Elysia, Next.js and Express'
|
||||||
|
/>
|
||||||
|
<Card
|
||||||
|
icon={<Cable />}
|
||||||
|
title='End to end typesafe APIs'
|
||||||
|
description='With the help of tRPC or oRPC'
|
||||||
|
/>
|
||||||
|
<Card
|
||||||
|
icon={<Lock />}
|
||||||
|
title='Authentication'
|
||||||
|
description='With the help of Better Auth'
|
||||||
|
/>
|
||||||
|
<Card
|
||||||
|
icon={<Database />}
|
||||||
|
title='Database Setup'
|
||||||
|
description='Many ORMs and Relational Databases'
|
||||||
|
/>
|
||||||
|
<Card
|
||||||
|
icon={<Package />}
|
||||||
|
title='Addons'
|
||||||
|
description='Add PWA support, desktop apps, documentation, and more'
|
||||||
|
/>
|
||||||
|
</Cards>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
---
|
---
|
||||||
title: Hello World
|
title: Introduction
|
||||||
description: Your first document
|
|
||||||
---
|
---
|
||||||
|
|
||||||
Welcome to the docs! You can start writing documents in `/content/docs`.
|
Better-T-Stack is a modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations.
|
||||||
|
|
||||||
## What is Next?
|
# Why Better-T-Stack?
|
||||||
|
|
||||||
<Cards>
|
Better-T-Stack lets you scaffold your projects for frontend, native apps, and backend with a single CLI command.
|
||||||
<Card title="Learn more about Next.js" href="https://nextjs.org/docs" />
|
|
||||||
<Card title="Learn more about Fumadocs" href="https://fumadocs.vercel.app" />
|
# Features
|
||||||
</Cards>
|
|
||||||
|
<Features />
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
title: Components
|
|
||||||
description: Components
|
|
||||||
---
|
|
||||||
|
|
||||||
## Code Block
|
|
||||||
|
|
||||||
```js
|
|
||||||
console.log('Hello World');
|
|
||||||
```
|
|
||||||
|
|
||||||
## Cards
|
|
||||||
|
|
||||||
<Cards>
|
|
||||||
<Card title="Learn more about Next.js" href="https://nextjs.org/docs" />
|
|
||||||
<Card title="Learn more about Fumadocs" href="https://fumadocs.vercel.app" />
|
|
||||||
</Cards>
|
|
||||||
@@ -1,45 +1,45 @@
|
|||||||
{
|
{
|
||||||
"name": "web",
|
"name": "web",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "next build",
|
"build": "next build",
|
||||||
"dev": "next dev --turbopack",
|
"dev": "next dev --turbopack",
|
||||||
"start": "next start",
|
"start": "next start",
|
||||||
"check": "biome check --write .",
|
"check": "biome check --write .",
|
||||||
"postinstall": "fumadocs-mdx"
|
"postinstall": "fumadocs-mdx"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroicons/react": "^2.2.0",
|
"@heroicons/react": "^2.2.0",
|
||||||
"@radix-ui/react-scroll-area": "^1.2.5",
|
"@radix-ui/react-scroll-area": "^1.2.5",
|
||||||
"@radix-ui/react-switch": "^1.2.2",
|
"@radix-ui/react-switch": "^1.2.2",
|
||||||
"@radix-ui/react-tooltip": "^1.2.4",
|
"@xyflow/react": "^12.5.5",
|
||||||
"@xyflow/react": "^12.5.5",
|
"babel-plugin-react-compiler": "^19.0.0-beta-e993439-20250405",
|
||||||
"babel-plugin-react-compiler": "^19.0.0-beta-e993439-20250405",
|
"class-variance-authority": "^0.7.1",
|
||||||
"class-variance-authority": "^0.7.1",
|
"clsx": "^2.1.1",
|
||||||
"clsx": "^2.1.1",
|
"fumadocs-core": "15.1.2",
|
||||||
"fumadocs-core": "15.1.2",
|
"fumadocs-mdx": "11.5.7",
|
||||||
"fumadocs-mdx": "11.5.7",
|
"fumadocs-ui": "15.1.2",
|
||||||
"fumadocs-ui": "15.1.2",
|
"lucide-react": "^0.501.0",
|
||||||
"lucide-react": "^0.501.0",
|
"motion": "^12.7.4",
|
||||||
"motion": "^12.7.4",
|
"next": "15.2.3",
|
||||||
"next": "15.2.3",
|
"nuqs": "^2.4.3",
|
||||||
"nuqs": "^2.4.3",
|
"react": "^19.1.0",
|
||||||
"react": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-tweet": "^3.2.2",
|
||||||
"react-tweet": "^3.2.2",
|
"tailwind-merge": "^3.2.0"
|
||||||
"tailwind-merge": "^3.2.0"
|
},
|
||||||
},
|
"devDependencies": {
|
||||||
"devDependencies": {
|
"@tailwindcss/postcss": "^4.1.3",
|
||||||
"@tailwindcss/postcss": "^4.1.3",
|
"@types/mdx": "^2.0.13",
|
||||||
"@types/mdx": "^2.0.13",
|
"@types/node": "22.13.11",
|
||||||
"@types/node": "22.13.11",
|
"@types/react": "^19.1.0",
|
||||||
"@types/react": "^19.1.0",
|
"@types/react-dom": "^19.1.1",
|
||||||
"@types/react-dom": "^19.1.1",
|
"eslint": "^9.24.0",
|
||||||
"eslint": "^9.24.0",
|
"eslint-config-next": "15.2.3",
|
||||||
"eslint-config-next": "15.2.3",
|
"postcss": "^8.5.3",
|
||||||
"postcss": "^8.5.3",
|
"tailwindcss": "^4.1.3",
|
||||||
"tailwindcss": "^4.1.3",
|
"tw-animate-css": "^1.0.0",
|
||||||
"typescript": "^5.8.3"
|
"typescript": "^5.8.3"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import { defineConfig, defineDocs } from "fumadocs-mdx/config";
|
import { defineConfig, defineDocs } from "fumadocs-mdx/config";
|
||||||
|
|
||||||
export const docs = defineDocs({
|
export const docs = defineDocs({
|
||||||
dir: "content/docs",
|
dir: "content/docs",
|
||||||
});
|
});
|
||||||
|
|
||||||
export default defineConfig({
|
export default defineConfig({
|
||||||
mdxOptions: {
|
mdxOptions: {
|
||||||
// MDX options
|
// MDX options
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,289 +1,319 @@
|
|||||||
"use client";
|
"use client";
|
||||||
import { cn } from "@/lib/utils";
|
import { cn } from "@/lib/utils";
|
||||||
import { Github, Maximize2, Menu, X } from "lucide-react";
|
import {
|
||||||
|
BookMarked,
|
||||||
|
BookMarkedIcon,
|
||||||
|
Github,
|
||||||
|
Maximize2,
|
||||||
|
Menu,
|
||||||
|
X,
|
||||||
|
} from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useEffect, useRef, useState } from "react";
|
import { useEffect, useRef, useState } from "react";
|
||||||
import PackageIcon from "./Icons";
|
import PackageIcon from "./Icons";
|
||||||
|
|
||||||
const Navbar = () => {
|
const Navbar = () => {
|
||||||
const [activeLink, setActiveLink] = useState("home");
|
const [activeLink, setActiveLink] = useState("home");
|
||||||
const [bgStyles, setBgStyles] = useState({});
|
const [bgStyles, setBgStyles] = useState({});
|
||||||
const [scrolled, setScrolled] = useState(false);
|
const [scrolled, setScrolled] = useState(false);
|
||||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
|
||||||
const linkRefs = useRef<{ [key: string]: HTMLAnchorElement | null }>({});
|
const linkRefs = useRef<{ [key: string]: HTMLAnchorElement | null }>({});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const updateBackground = (linkId: string) => {
|
const updateBackground = (linkId: string) => {
|
||||||
const linkElement = linkRefs.current[linkId];
|
const linkElement = linkRefs.current[linkId];
|
||||||
if (linkElement) {
|
if (linkElement) {
|
||||||
setBgStyles({
|
setBgStyles({
|
||||||
padding: "0.75rem 0rem",
|
padding: "0.75rem 0rem",
|
||||||
width: `${linkElement.clientWidth - 12}px`,
|
width: `${linkElement.clientWidth - 12}px`,
|
||||||
transform: `translateX(${linkElement.offsetLeft}px)`,
|
transform: `translateX(${linkElement.offsetLeft}px)`,
|
||||||
opacity: 1,
|
opacity: 1,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
updateBackground(activeLink);
|
updateBackground(activeLink);
|
||||||
|
|
||||||
const handleScroll = () => {
|
const handleScroll = () => {
|
||||||
const isScrolled = window.scrollY > 50;
|
const isScrolled = window.scrollY > 50;
|
||||||
setScrolled(isScrolled);
|
setScrolled(isScrolled);
|
||||||
};
|
};
|
||||||
|
|
||||||
window.addEventListener("scroll", handleScroll);
|
window.addEventListener("scroll", handleScroll);
|
||||||
window.addEventListener("resize", () => updateBackground(activeLink));
|
window.addEventListener("resize", () => updateBackground(activeLink));
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
window.removeEventListener("scroll", handleScroll);
|
window.removeEventListener("scroll", handleScroll);
|
||||||
window.removeEventListener("resize", () => updateBackground(activeLink));
|
window.removeEventListener("resize", () => updateBackground(activeLink));
|
||||||
};
|
};
|
||||||
}, [activeLink]);
|
}, [activeLink]);
|
||||||
|
|
||||||
const toggleMobileMenu = () => {
|
const toggleMobileMenu = () => {
|
||||||
setMobileMenuOpen(!mobileMenuOpen);
|
setMobileMenuOpen(!mobileMenuOpen);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<nav
|
<nav
|
||||||
className={cn(
|
className={cn(
|
||||||
"fixed top-0 z-[100] flex w-full items-center justify-between px-4 py-4 transition-all duration-300 sm:px-8",
|
"fixed top-0 z-[100] flex w-full items-center justify-between px-4 py-4 transition-all duration-300 sm:px-8",
|
||||||
scrolled ? "bg-transparent" : "bg-background/80 backdrop-blur-xl",
|
scrolled ? "bg-transparent" : "bg-background/80 backdrop-blur-xl"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"flex flex-row items-center space-x-3 transition-opacity duration-300",
|
"flex flex-row items-center space-x-3 transition-opacity duration-300",
|
||||||
scrolled ? "opacity-0" : "opacity-100",
|
scrolled ? "opacity-0" : "opacity-100"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div className="flex h-4 w-4 items-center justify-center rounded-sm">
|
<div className='flex h-4 w-4 items-center justify-center rounded-sm'>
|
||||||
<span className="text-md text-primary">$_</span>
|
<span className='text-md text-primary'>$_</span>
|
||||||
</div>
|
</div>
|
||||||
<span className="font-semibold text-foreground text-md">
|
<span className='font-semibold text-foreground text-md'>
|
||||||
Better-T Stack
|
Better-T Stack
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="-translate-x-1/2 absolute left-1/2 hidden transform md:block">
|
<div className='-translate-x-1/2 absolute left-1/2 hidden transform md:block'>
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"relative flex items-center rounded-lg border border-border bg-muted/90 px-1.5 py-1 text-sm backdrop-blur-sm transition-all duration-500 ease-out",
|
"relative flex items-center rounded-lg border border-border bg-muted/90 px-1.5 py-1 text-sm backdrop-blur-sm transition-all duration-500 ease-out",
|
||||||
scrolled ? "w-[352px]" : "w-[245px]",
|
scrolled ? "w-[420px]" : "w-[313px]"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className="absolute rounded-md bg-background transition-all duration-200 ease-in-out"
|
className='absolute rounded-md bg-background transition-all duration-200 ease-in-out'
|
||||||
style={bgStyles}
|
style={bgStyles}
|
||||||
/>
|
/>
|
||||||
<Link
|
<Link
|
||||||
href="/"
|
href='/'
|
||||||
ref={(ref) => {
|
ref={(ref) => {
|
||||||
linkRefs.current.home = ref;
|
linkRefs.current.home = ref;
|
||||||
}}
|
}}
|
||||||
onMouseOver={() => setActiveLink("home")}
|
onMouseOver={() => setActiveLink("home")}
|
||||||
className="relative flex items-center gap-1 rounded-md px-4 py-2 font-mono text-muted-foreground transition-colors hover:text-primary"
|
className='relative flex items-center gap-1 rounded-md px-4 py-2 font-mono text-muted-foreground transition-colors hover:text-primary'
|
||||||
>
|
>
|
||||||
<span className="text-primary">~/</span>
|
<span className='text-primary'>~/</span>
|
||||||
home
|
home
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
href="https://my-better-t-app-client.pages.dev/"
|
href='https://my-better-t-app-client.pages.dev/'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
ref={(ref) => {
|
ref={(ref) => {
|
||||||
linkRefs.current.demo = ref;
|
linkRefs.current.demo = ref;
|
||||||
}}
|
}}
|
||||||
onMouseOver={() => setActiveLink("demo")}
|
onMouseOver={() => setActiveLink("demo")}
|
||||||
onMouseLeave={() => setActiveLink("home")}
|
onMouseLeave={() => setActiveLink("home")}
|
||||||
className="relative flex items-center gap-2 rounded-md px-4 py-2 font-mono text-muted-foreground transition-colors hover:text-primary"
|
className='relative flex items-center gap-2 rounded-md px-4 py-2 font-mono text-muted-foreground transition-colors hover:text-primary'
|
||||||
>
|
>
|
||||||
<span>demo</span>
|
<span>demo</span>
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
href="https://www.npmjs.com/package/create-better-t-stack"
|
href='/docs'
|
||||||
target="_blank"
|
ref={(ref) => {
|
||||||
ref={(ref) => {
|
linkRefs.current.docs = ref;
|
||||||
linkRefs.current.npm = ref;
|
}}
|
||||||
}}
|
onMouseOver={() => setActiveLink("docs")}
|
||||||
onMouseOver={() => setActiveLink("npm")}
|
onMouseLeave={() => setActiveLink("home")}
|
||||||
onMouseLeave={() => setActiveLink("home")}
|
className='relative flex items-center gap-2 rounded-md px-4 py-2 font-mono text-muted-foreground transition-colors hover:text-primary'
|
||||||
className="relative flex items-center gap-2 rounded-md px-4 py-2 font-mono text-muted-foreground transition-colors hover:text-primary"
|
>
|
||||||
>
|
<span>docs</span>
|
||||||
<PackageIcon pm="npm" className="h-4 w-4 rounded-full" />{" "}
|
</Link>
|
||||||
<span>npm</span>
|
|
||||||
</Link>
|
|
||||||
|
|
||||||
<Link
|
<Link
|
||||||
href="https://www.github.com/better-t-stack/create-better-t-stack"
|
href='https://www.npmjs.com/package/create-better-t-stack'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
ref={(ref) => {
|
ref={(ref) => {
|
||||||
linkRefs.current.github = ref;
|
linkRefs.current.npm = ref;
|
||||||
}}
|
}}
|
||||||
onMouseOver={() => setActiveLink("github")}
|
onMouseOver={() => setActiveLink("npm")}
|
||||||
onMouseLeave={() => setActiveLink("home")}
|
onMouseLeave={() => setActiveLink("home")}
|
||||||
className={cn(
|
className='relative flex items-center gap-2 rounded-md px-4 py-2 font-mono text-muted-foreground transition-colors hover:text-primary'
|
||||||
"relative flex items-center gap-2 rounded-md px-4 py-2 font-mono text-muted-foreground transition-colors hover:text-primary",
|
>
|
||||||
scrolled
|
<PackageIcon pm='npm' className='h-4 w-4 rounded-full' />{" "}
|
||||||
? "translate-y-0 opacity-100"
|
<span>npm</span>
|
||||||
: "pointer-events-none opacity-0",
|
</Link>
|
||||||
)}
|
|
||||||
>
|
|
||||||
<Github className="size-4">
|
|
||||||
<title>GitHub</title>
|
|
||||||
</Github>
|
|
||||||
Github
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
<Link
|
||||||
className={cn(
|
href='https://www.github.com/better-t-stack/create-better-t-stack'
|
||||||
"hidden justify-end gap-2 transition-opacity duration-300 md:flex",
|
target='_blank'
|
||||||
scrolled ? "pointer-events-none opacity-0" : "opacity-100",
|
ref={(ref) => {
|
||||||
)}
|
linkRefs.current.github = ref;
|
||||||
>
|
}}
|
||||||
<Link
|
onMouseOver={() => setActiveLink("github")}
|
||||||
href="/new"
|
onMouseLeave={() => setActiveLink("home")}
|
||||||
className="inline-flex items-center rounded-lg border border-primary/50 bg-primary/10 px-4 py-1 font-mono text-primary text-sm backdrop-blur-sm transition-colors hover:bg-primary/20"
|
className={cn(
|
||||||
>
|
"relative flex items-center gap-2 rounded-md px-4 py-2 font-mono text-muted-foreground transition-colors hover:text-primary",
|
||||||
<Maximize2 className="mr-1 size-4" />
|
scrolled
|
||||||
Stack Builder
|
? "translate-y-0 opacity-100"
|
||||||
</Link>
|
: "pointer-events-none opacity-0"
|
||||||
<Link
|
)}
|
||||||
href="https://www.github.com/better-t-stack/create-better-t-stack"
|
>
|
||||||
target="_blank"
|
<Github className='size-4'>
|
||||||
className="inline-flex items-center rounded-lg border border-border bg-muted/90 px-4 py-1 font-mono text-muted-foreground text-sm backdrop-blur-sm transition-colors hover:bg-muted hover:text-primary"
|
<title>GitHub</title>
|
||||||
>
|
</Github>
|
||||||
<Github className="mr-1 size-4">
|
Github
|
||||||
<title>GitHub</title>
|
</Link>
|
||||||
</Github>
|
</div>
|
||||||
Star on GitHub
|
</div>
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<button
|
<div
|
||||||
type="button"
|
className={cn(
|
||||||
onClick={toggleMobileMenu}
|
"hidden justify-end gap-2 transition-opacity duration-300 md:flex",
|
||||||
className="flex items-center justify-center rounded-md p-2 text-foreground hover:bg-muted/50 focus:outline-none md:hidden"
|
scrolled ? "pointer-events-none opacity-0" : "opacity-100"
|
||||||
aria-expanded={mobileMenuOpen}
|
)}
|
||||||
>
|
>
|
||||||
{mobileMenuOpen ? (
|
<Link
|
||||||
<X className="size-5" aria-hidden="true" />
|
href='/new'
|
||||||
) : (
|
className='inline-flex items-center rounded-lg border border-primary/50 bg-primary/10 px-4 py-1 font-mono text-primary text-sm backdrop-blur-sm transition-colors hover:bg-primary/20'
|
||||||
<Menu className="size-5" aria-hidden="true" />
|
>
|
||||||
)}
|
<Maximize2 className='mr-1 size-4' />
|
||||||
<span className="sr-only">Toggle menu</span>
|
Stack Builder
|
||||||
</button>
|
</Link>
|
||||||
</nav>
|
<Link
|
||||||
|
href='https://www.github.com/better-t-stack/create-better-t-stack'
|
||||||
|
target='_blank'
|
||||||
|
className='inline-flex items-center rounded-lg border border-border bg-muted/90 px-4 py-1 font-mono text-muted-foreground text-sm backdrop-blur-sm transition-colors hover:bg-muted hover:text-primary'
|
||||||
|
>
|
||||||
|
<Github className='mr-1 size-4'>
|
||||||
|
<title>GitHub</title>
|
||||||
|
</Github>
|
||||||
|
Star on GitHub
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div
|
<button
|
||||||
className={cn(
|
type='button'
|
||||||
"fixed inset-0 z-[99] pt-16 backdrop-blur-md transition-all duration-300 ease-in-out md:hidden",
|
onClick={toggleMobileMenu}
|
||||||
mobileMenuOpen
|
className='flex items-center justify-center rounded-md p-2 text-foreground hover:bg-muted/50 focus:outline-none md:hidden'
|
||||||
? "pointer-events-auto opacity-100"
|
aria-expanded={mobileMenuOpen}
|
||||||
: "pointer-events-none opacity-0",
|
>
|
||||||
)}
|
{mobileMenuOpen ? (
|
||||||
>
|
<X className='size-5' aria-hidden='true' />
|
||||||
<div className="mx-4 mt-4 overflow-hidden rounded-lg border border-border bg-background/95">
|
) : (
|
||||||
<div className="flex items-center bg-muted px-4 py-2">
|
<Menu className='size-5' aria-hidden='true' />
|
||||||
<div className="mr-4 flex space-x-2">
|
)}
|
||||||
<div className="h-3 w-3 rounded-full bg-red-500" />
|
<span className='sr-only'>Toggle menu</span>
|
||||||
<div className="h-3 w-3 rounded-full bg-yellow-500" />
|
</button>
|
||||||
<div className="h-3 w-3 rounded-full bg-green-500" />
|
</nav>
|
||||||
</div>
|
|
||||||
<div className="font-mono text-muted-foreground text-sm">
|
|
||||||
better-t-stack:~
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="p-4 font-mono text-sm">
|
<div
|
||||||
<div className="pb-3">
|
className={cn(
|
||||||
<span className="text-[--color-chart-4]">
|
"fixed inset-0 z-[99] pt-16 backdrop-blur-md transition-all duration-300 ease-in-out md:hidden",
|
||||||
user@better-t-stack
|
mobileMenuOpen
|
||||||
</span>
|
? "pointer-events-auto opacity-100"
|
||||||
<span className="text-muted-foreground">:~$</span>
|
: "pointer-events-none opacity-0"
|
||||||
<span className="ml-2 text-foreground">ls -la</span>
|
)}
|
||||||
</div>
|
>
|
||||||
|
<div className='mx-4 mt-4 overflow-hidden rounded-lg border border-border bg-background/95'>
|
||||||
|
<div className='flex items-center bg-muted px-4 py-2'>
|
||||||
|
<div className='mr-4 flex space-x-2'>
|
||||||
|
<div className='h-3 w-3 rounded-full bg-red-500' />
|
||||||
|
<div className='h-3 w-3 rounded-full bg-yellow-500' />
|
||||||
|
<div className='h-3 w-3 rounded-full bg-green-500' />
|
||||||
|
</div>
|
||||||
|
<div className='font-mono text-muted-foreground text-sm'>
|
||||||
|
better-t-stack:~
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="space-y-2 border-border border-l-2 pl-4">
|
<div className='p-4 font-mono text-sm'>
|
||||||
<Link
|
<div className='pb-3'>
|
||||||
href="/"
|
<span className='text-[--color-chart-4]'>
|
||||||
className="block text-primary hover:underline"
|
user@better-t-stack
|
||||||
onClick={() => setMobileMenuOpen(false)}
|
</span>
|
||||||
>
|
<span className='text-muted-foreground'>:~$</span>
|
||||||
~/home
|
<span className='ml-2 text-foreground'>ls -la</span>
|
||||||
</Link>
|
</div>
|
||||||
|
|
||||||
<Link
|
<div className='space-y-2 border-border border-l-2 pl-4'>
|
||||||
href="https://my-better-t-app-client.pages.dev/"
|
<Link
|
||||||
target="_blank"
|
href='/'
|
||||||
className="block text-primary hover:underline"
|
className='block text-primary hover:underline'
|
||||||
onClick={() => setMobileMenuOpen(false)}
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
>
|
>
|
||||||
~/demo
|
~/home
|
||||||
</Link>
|
</Link>
|
||||||
|
|
||||||
<div className="flex items-center">
|
<Link
|
||||||
<PackageIcon pm="npm" className="mr-1 h-4 w-4" />
|
href='https://my-better-t-app-client.pages.dev/'
|
||||||
<Link
|
target='_blank'
|
||||||
href="https://www.npmjs.com/package/create-better-t-stack"
|
className='block text-primary hover:underline'
|
||||||
target="_blank"
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
className="block text-primary hover:underline"
|
>
|
||||||
onClick={() => setMobileMenuOpen(false)}
|
~/demo
|
||||||
>
|
</Link>
|
||||||
~/npm
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="flex items-center">
|
<div className='flex items-center'>
|
||||||
<Github className="mr-1 size-4 text-foreground" />
|
<PackageIcon pm='npm' className='mr-1 h-4 w-4' />
|
||||||
<Link
|
<Link
|
||||||
href="https://www.github.com/better-t-stack/create-better-t-stack"
|
href='https://www.npmjs.com/package/create-better-t-stack'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
className="block text-primary hover:underline"
|
className='block text-primary hover:underline'
|
||||||
onClick={() => setMobileMenuOpen(false)}
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
>
|
>
|
||||||
~/github
|
~/npm
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mt-6 pb-3">
|
<div className='flex items-center'>
|
||||||
<span className="text-[--color-chart-4]">
|
<BookMarked className='mr-1 h-4 w-4' />
|
||||||
user@better-t-stack
|
<Link
|
||||||
</span>
|
href='/docs'
|
||||||
<span className="text-muted-foreground">:~$</span>
|
className='block text-primary hover:underline'
|
||||||
<span className="ml-2 text-foreground">star-repo</span>
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
</div>
|
>
|
||||||
|
~/docs
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="border-border border-l-2 pb-2 pl-4">
|
<div className='flex items-center'>
|
||||||
<Link
|
<Github className='mr-1 size-4 text-foreground' />
|
||||||
href="https://www.github.com/better-t-stack/create-better-t-stack"
|
<Link
|
||||||
target="_blank"
|
href='https://www.github.com/better-t-stack/create-better-t-stack'
|
||||||
className="inline-flex items-center rounded-md bg-muted px-4 py-2 text-foreground transition-colors hover:bg-muted/80"
|
target='_blank'
|
||||||
onClick={() => setMobileMenuOpen(false)}
|
className='block text-primary hover:underline'
|
||||||
>
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
<Github className="mr-1 size-5" />
|
>
|
||||||
Star on GitHub
|
~/github
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div className="mt-4">
|
<div className='mt-6 pb-3'>
|
||||||
<span className="text-[--color-chart-4]">
|
<span className='text-[--color-chart-4]'>
|
||||||
user@better-t-stack
|
user@better-t-stack
|
||||||
</span>
|
</span>
|
||||||
<span className="text-muted-foreground">:~$</span>
|
<span className='text-muted-foreground'>:~$</span>
|
||||||
<span className="ml-2 animate-pulse text-foreground">█</span>
|
<span className='ml-2 text-foreground'>star-repo</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
<div className='border-border border-l-2 pb-2 pl-4'>
|
||||||
</div>
|
<Link
|
||||||
</>
|
href='https://www.github.com/better-t-stack/create-better-t-stack'
|
||||||
);
|
target='_blank'
|
||||||
|
className='inline-flex items-center rounded-md bg-muted px-4 py-2 text-foreground transition-colors hover:bg-muted/80'
|
||||||
|
onClick={() => setMobileMenuOpen(false)}
|
||||||
|
>
|
||||||
|
<Github className='mr-1 size-5' />
|
||||||
|
Star on GitHub
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='mt-4'>
|
||||||
|
<span className='text-[--color-chart-4]'>
|
||||||
|
user@better-t-stack
|
||||||
|
</span>
|
||||||
|
<span className='text-muted-foreground'>:~$</span>
|
||||||
|
<span className='ml-2 animate-pulse text-foreground'>█</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
export default Navbar;
|
export default Navbar;
|
||||||
|
|||||||
@@ -1,46 +1,47 @@
|
|||||||
import { source } from "@/lib/source";
|
import { source } from "@/lib/source";
|
||||||
import defaultMdxComponents from "fumadocs-ui/mdx";
|
import defaultMdxComponents from "fumadocs-ui/mdx";
|
||||||
|
import Features from "components/features";
|
||||||
import {
|
import {
|
||||||
DocsBody,
|
DocsBody,
|
||||||
DocsDescription,
|
DocsDescription,
|
||||||
DocsPage,
|
DocsPage,
|
||||||
DocsTitle,
|
DocsTitle,
|
||||||
} from "fumadocs-ui/page";
|
} from "fumadocs-ui/page";
|
||||||
import { notFound } from "next/navigation";
|
import { notFound } from "next/navigation";
|
||||||
|
|
||||||
export default async function Page(props: {
|
export default async function Page(props: {
|
||||||
params: Promise<{ slug?: string[] }>;
|
params: Promise<{ slug?: string[] }>;
|
||||||
}) {
|
}) {
|
||||||
const params = await props.params;
|
const params = await props.params;
|
||||||
const page = source.getPage(params.slug);
|
const page = source.getPage(params.slug);
|
||||||
if (!page) notFound();
|
if (!page) notFound();
|
||||||
|
|
||||||
const MDX = page.data.body;
|
const MDX = page.data.body;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DocsPage toc={page.data.toc} full={page.data.full}>
|
<DocsPage toc={page.data.toc} full={page.data.full}>
|
||||||
<DocsTitle>{page.data.title}</DocsTitle>
|
<DocsTitle>{page.data.title}</DocsTitle>
|
||||||
<DocsDescription>{page.data.description}</DocsDescription>
|
<DocsDescription>{page.data.description}</DocsDescription>
|
||||||
<DocsBody>
|
<DocsBody>
|
||||||
<MDX components={{ ...defaultMdxComponents }} />
|
<MDX components={{ ...defaultMdxComponents, Features }} />
|
||||||
</DocsBody>
|
</DocsBody>
|
||||||
</DocsPage>
|
</DocsPage>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateStaticParams() {
|
export async function generateStaticParams() {
|
||||||
return source.generateParams();
|
return source.generateParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function generateMetadata(props: {
|
export async function generateMetadata(props: {
|
||||||
params: Promise<{ slug?: string[] }>;
|
params: Promise<{ slug?: string[] }>;
|
||||||
}) {
|
}) {
|
||||||
const params = await props.params;
|
const params = await props.params;
|
||||||
const page = source.getPage(params.slug);
|
const page = source.getPage(params.slug);
|
||||||
if (!page) notFound();
|
if (!page) notFound();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
title: page.data.title,
|
title: page.data.title,
|
||||||
description: page.data.description,
|
description: page.data.description,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
|
import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
|
||||||
|
import { BookMarked } from "lucide-react";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shared layout configurations
|
* Shared layout configurations
|
||||||
@@ -8,15 +9,23 @@ import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared";
|
|||||||
* Docs Layout: app/docs/layout.tsx
|
* Docs Layout: app/docs/layout.tsx
|
||||||
*/
|
*/
|
||||||
export const baseOptions: BaseLayoutProps = {
|
export const baseOptions: BaseLayoutProps = {
|
||||||
nav: {
|
nav: {
|
||||||
title: "Better-T-Stack",
|
title: "Better-T-Stack",
|
||||||
enabled: false,
|
enabled: false,
|
||||||
},
|
},
|
||||||
links: [
|
links: [
|
||||||
{
|
{
|
||||||
text: "Documentation",
|
children: (
|
||||||
url: "/docs",
|
<a
|
||||||
active: "nested-url",
|
className='border-muted flex border rounded-lg p-2 text-lg items-center gap-2'
|
||||||
},
|
href='/docs'
|
||||||
],
|
>
|
||||||
|
<BookMarked size={16} />
|
||||||
|
Documentation
|
||||||
|
</a>
|
||||||
|
),
|
||||||
|
type: "custom",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
githubUrl: "https://github.com/AmanVarshney01/create-better-t-stack",
|
||||||
};
|
};
|
||||||
|
|||||||
3
bun.lock
3
bun.lock
@@ -72,6 +72,7 @@
|
|||||||
"eslint-config-next": "15.2.3",
|
"eslint-config-next": "15.2.3",
|
||||||
"postcss": "^8.5.3",
|
"postcss": "^8.5.3",
|
||||||
"tailwindcss": "^4.1.3",
|
"tailwindcss": "^4.1.3",
|
||||||
|
"tw-animate-css": "^1.0.0",
|
||||||
"typescript": "^5.8.3",
|
"typescript": "^5.8.3",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -1625,6 +1626,8 @@
|
|||||||
|
|
||||||
"turbo-windows-arm64": ["turbo-windows-arm64@2.5.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-OUHCV+ueXa3UzfZ4co/ueIHgeq9B2K48pZwIxKSm5VaLVuv8M13MhM7unukW09g++dpdrrE1w4IOVgxKZ0/exg=="],
|
"turbo-windows-arm64": ["turbo-windows-arm64@2.5.0", "", { "os": "win32", "cpu": "arm64" }, "sha512-OUHCV+ueXa3UzfZ4co/ueIHgeq9B2K48pZwIxKSm5VaLVuv8M13MhM7unukW09g++dpdrrE1w4IOVgxKZ0/exg=="],
|
||||||
|
|
||||||
|
"tw-animate-css": ["tw-animate-css@1.2.7", "", {}, "sha512-7JejnC2dkGrV2ZqBioKslkPVRBAFZNuASkBzj2kJb08aoVkvWOFZD8LDfeTH3+l3vPjP7DtY8RppluF7wRrktA=="],
|
||||||
|
|
||||||
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
|
||||||
|
|
||||||
"typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
|
"typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
|
||||||
|
|||||||
Reference in New Issue
Block a user