diff --git a/apps/web/components/features.tsx b/apps/web/components/features.tsx new file mode 100644 index 0000000..4541d18 --- /dev/null +++ b/apps/web/components/features.tsx @@ -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 ( + + } + title='Frontend' + description='Choose between Tanstack Router, React Router, Expo, Next.js, and more' + /> + } + title='Flexible Backend' + description='Choose between Hono, Elysia, Next.js and Express' + /> + } + title='End to end typesafe APIs' + description='With the help of tRPC or oRPC' + /> + } + title='Authentication' + description='With the help of Better Auth' + /> + } + title='Database Setup' + description='Many ORMs and Relational Databases' + /> + } + title='Addons' + description='Add PWA support, desktop apps, documentation, and more' + /> + + ); +} diff --git a/apps/web/content/docs/index.mdx b/apps/web/content/docs/index.mdx index 986a7fa..33afe83 100644 --- a/apps/web/content/docs/index.mdx +++ b/apps/web/content/docs/index.mdx @@ -1,13 +1,13 @@ --- -title: Hello World -description: Your first document +title: Introduction --- -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? - - - - +Better-T-Stack lets you scaffold your projects for frontend, native apps, and backend with a single CLI command. + +# Features + + diff --git a/apps/web/content/docs/test.mdx b/apps/web/content/docs/test.mdx deleted file mode 100644 index d1ee3a8..0000000 --- a/apps/web/content/docs/test.mdx +++ /dev/null @@ -1,17 +0,0 @@ ---- -title: Components -description: Components ---- - -## Code Block - -```js -console.log('Hello World'); -``` - -## Cards - - - - - diff --git a/apps/web/package.json b/apps/web/package.json index 5b4392d..b55dcbe 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -1,45 +1,45 @@ { - "name": "web", - "version": "0.0.0", - "private": true, - "scripts": { - "build": "next build", - "dev": "next dev --turbopack", - "start": "next start", - "check": "biome check --write .", - "postinstall": "fumadocs-mdx" - }, - "dependencies": { - "@heroicons/react": "^2.2.0", - "@radix-ui/react-scroll-area": "^1.2.5", - "@radix-ui/react-switch": "^1.2.2", - "@radix-ui/react-tooltip": "^1.2.4", - "@xyflow/react": "^12.5.5", - "babel-plugin-react-compiler": "^19.0.0-beta-e993439-20250405", - "class-variance-authority": "^0.7.1", - "clsx": "^2.1.1", - "fumadocs-core": "15.1.2", - "fumadocs-mdx": "11.5.7", - "fumadocs-ui": "15.1.2", - "lucide-react": "^0.501.0", - "motion": "^12.7.4", - "next": "15.2.3", - "nuqs": "^2.4.3", - "react": "^19.1.0", - "react-dom": "^19.1.0", - "react-tweet": "^3.2.2", - "tailwind-merge": "^3.2.0" - }, - "devDependencies": { - "@tailwindcss/postcss": "^4.1.3", - "@types/mdx": "^2.0.13", - "@types/node": "22.13.11", - "@types/react": "^19.1.0", - "@types/react-dom": "^19.1.1", - "eslint": "^9.24.0", - "eslint-config-next": "15.2.3", - "postcss": "^8.5.3", - "tailwindcss": "^4.1.3", - "typescript": "^5.8.3" - } + "name": "web", + "version": "0.0.0", + "private": true, + "scripts": { + "build": "next build", + "dev": "next dev --turbopack", + "start": "next start", + "check": "biome check --write .", + "postinstall": "fumadocs-mdx" + }, + "dependencies": { + "@heroicons/react": "^2.2.0", + "@radix-ui/react-scroll-area": "^1.2.5", + "@radix-ui/react-switch": "^1.2.2", + "@xyflow/react": "^12.5.5", + "babel-plugin-react-compiler": "^19.0.0-beta-e993439-20250405", + "class-variance-authority": "^0.7.1", + "clsx": "^2.1.1", + "fumadocs-core": "15.1.2", + "fumadocs-mdx": "11.5.7", + "fumadocs-ui": "15.1.2", + "lucide-react": "^0.501.0", + "motion": "^12.7.4", + "next": "15.2.3", + "nuqs": "^2.4.3", + "react": "^19.1.0", + "react-dom": "^19.1.0", + "react-tweet": "^3.2.2", + "tailwind-merge": "^3.2.0" + }, + "devDependencies": { + "@tailwindcss/postcss": "^4.1.3", + "@types/mdx": "^2.0.13", + "@types/node": "22.13.11", + "@types/react": "^19.1.0", + "@types/react-dom": "^19.1.1", + "eslint": "^9.24.0", + "eslint-config-next": "15.2.3", + "postcss": "^8.5.3", + "tailwindcss": "^4.1.3", + "tw-animate-css": "^1.0.0", + "typescript": "^5.8.3" + } } diff --git a/apps/web/source.config.ts b/apps/web/source.config.ts index df8d905..6b183f3 100644 --- a/apps/web/source.config.ts +++ b/apps/web/source.config.ts @@ -1,11 +1,11 @@ import { defineConfig, defineDocs } from "fumadocs-mdx/config"; export const docs = defineDocs({ - dir: "content/docs", + dir: "content/docs", }); export default defineConfig({ - mdxOptions: { - // MDX options - }, + mdxOptions: { + // MDX options + }, }); diff --git a/apps/web/src/app/(home)/_components/Navbar.tsx b/apps/web/src/app/(home)/_components/Navbar.tsx index 8584be2..9fcf01e 100644 --- a/apps/web/src/app/(home)/_components/Navbar.tsx +++ b/apps/web/src/app/(home)/_components/Navbar.tsx @@ -1,289 +1,319 @@ "use client"; 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 { useEffect, useRef, useState } from "react"; import PackageIcon from "./Icons"; const Navbar = () => { - const [activeLink, setActiveLink] = useState("home"); - const [bgStyles, setBgStyles] = useState({}); - const [scrolled, setScrolled] = useState(false); - const [mobileMenuOpen, setMobileMenuOpen] = useState(false); - const linkRefs = useRef<{ [key: string]: HTMLAnchorElement | null }>({}); + const [activeLink, setActiveLink] = useState("home"); + const [bgStyles, setBgStyles] = useState({}); + const [scrolled, setScrolled] = useState(false); + const [mobileMenuOpen, setMobileMenuOpen] = useState(false); + const linkRefs = useRef<{ [key: string]: HTMLAnchorElement | null }>({}); - useEffect(() => { - const updateBackground = (linkId: string) => { - const linkElement = linkRefs.current[linkId]; - if (linkElement) { - setBgStyles({ - padding: "0.75rem 0rem", - width: `${linkElement.clientWidth - 12}px`, - transform: `translateX(${linkElement.offsetLeft}px)`, - opacity: 1, - }); - } - }; + useEffect(() => { + const updateBackground = (linkId: string) => { + const linkElement = linkRefs.current[linkId]; + if (linkElement) { + setBgStyles({ + padding: "0.75rem 0rem", + width: `${linkElement.clientWidth - 12}px`, + transform: `translateX(${linkElement.offsetLeft}px)`, + opacity: 1, + }); + } + }; - updateBackground(activeLink); + updateBackground(activeLink); - const handleScroll = () => { - const isScrolled = window.scrollY > 50; - setScrolled(isScrolled); - }; + const handleScroll = () => { + const isScrolled = window.scrollY > 50; + setScrolled(isScrolled); + }; - window.addEventListener("scroll", handleScroll); - window.addEventListener("resize", () => updateBackground(activeLink)); + window.addEventListener("scroll", handleScroll); + window.addEventListener("resize", () => updateBackground(activeLink)); - return () => { - window.removeEventListener("scroll", handleScroll); - window.removeEventListener("resize", () => updateBackground(activeLink)); - }; - }, [activeLink]); + return () => { + window.removeEventListener("scroll", handleScroll); + window.removeEventListener("resize", () => updateBackground(activeLink)); + }; + }, [activeLink]); - const toggleMobileMenu = () => { - setMobileMenuOpen(!mobileMenuOpen); - }; + const toggleMobileMenu = () => { + setMobileMenuOpen(!mobileMenuOpen); + }; - return ( - <> - -
-
- - user@better-t-stack - - :~$ - ls -la -
+
+
+
+
+
+
+
+
+
+ better-t-stack:~ +
+
-
- setMobileMenuOpen(false)} - > - ~/home - +
+
+ + user@better-t-stack + + :~$ + ls -la +
- setMobileMenuOpen(false)} - > - ~/demo - +
+ setMobileMenuOpen(false)} + > + ~/home + -
- - setMobileMenuOpen(false)} - > - ~/npm - -
+ setMobileMenuOpen(false)} + > + ~/demo + -
- - setMobileMenuOpen(false)} - > - ~/github - -
-
+
+ + setMobileMenuOpen(false)} + > + ~/npm + +
-
- - user@better-t-stack - - :~$ - star-repo -
+
+ + setMobileMenuOpen(false)} + > + ~/docs + +
-
- setMobileMenuOpen(false)} - > - - Star on GitHub - -
+
+ + setMobileMenuOpen(false)} + > + ~/github + +
+
-
- - user@better-t-stack - - :~$ - -
-
-
-
- - ); +
+ + user@better-t-stack + + :~$ + star-repo +
+ +
+ setMobileMenuOpen(false)} + > + + Star on GitHub + +
+ +
+ + user@better-t-stack + + :~$ + +
+
+
+
+ + ); }; export default Navbar; diff --git a/apps/web/src/app/docs/[[...slug]]/page.tsx b/apps/web/src/app/docs/[[...slug]]/page.tsx index 991568f..0a0c637 100644 --- a/apps/web/src/app/docs/[[...slug]]/page.tsx +++ b/apps/web/src/app/docs/[[...slug]]/page.tsx @@ -1,46 +1,47 @@ import { source } from "@/lib/source"; import defaultMdxComponents from "fumadocs-ui/mdx"; +import Features from "components/features"; import { - DocsBody, - DocsDescription, - DocsPage, - DocsTitle, + DocsBody, + DocsDescription, + DocsPage, + DocsTitle, } from "fumadocs-ui/page"; import { notFound } from "next/navigation"; export default async function Page(props: { - params: Promise<{ slug?: string[] }>; + params: Promise<{ slug?: string[] }>; }) { - const params = await props.params; - const page = source.getPage(params.slug); - if (!page) notFound(); + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); - const MDX = page.data.body; + const MDX = page.data.body; - return ( - - {page.data.title} - {page.data.description} - - - - - ); + return ( + + {page.data.title} + {page.data.description} + + + + + ); } export async function generateStaticParams() { - return source.generateParams(); + return source.generateParams(); } export async function generateMetadata(props: { - params: Promise<{ slug?: string[] }>; + params: Promise<{ slug?: string[] }>; }) { - const params = await props.params; - const page = source.getPage(params.slug); - if (!page) notFound(); + const params = await props.params; + const page = source.getPage(params.slug); + if (!page) notFound(); - return { - title: page.data.title, - description: page.data.description, - }; + return { + title: page.data.title, + description: page.data.description, + }; } diff --git a/apps/web/src/app/layout.config.tsx b/apps/web/src/app/layout.config.tsx index 2e62b1f..b5eac23 100644 --- a/apps/web/src/app/layout.config.tsx +++ b/apps/web/src/app/layout.config.tsx @@ -1,4 +1,5 @@ import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared"; +import { BookMarked } from "lucide-react"; /** * Shared layout configurations @@ -8,15 +9,23 @@ import type { BaseLayoutProps } from "fumadocs-ui/layouts/shared"; * Docs Layout: app/docs/layout.tsx */ export const baseOptions: BaseLayoutProps = { - nav: { - title: "Better-T-Stack", - enabled: false, - }, - links: [ - { - text: "Documentation", - url: "/docs", - active: "nested-url", - }, - ], + nav: { + title: "Better-T-Stack", + enabled: false, + }, + links: [ + { + children: ( + + + Documentation + + ), + type: "custom", + }, + ], + githubUrl: "https://github.com/AmanVarshney01/create-better-t-stack", }; diff --git a/bun.lock b/bun.lock index 8f9c233..83d24fb 100644 --- a/bun.lock +++ b/bun.lock @@ -72,6 +72,7 @@ "eslint-config-next": "15.2.3", "postcss": "^8.5.3", "tailwindcss": "^4.1.3", + "tw-animate-css": "^1.0.0", "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=="], + "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=="], "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=="],