chore: initial Next.js template scaffold
Next.js 16 + React 19 + TypeScript 5 + Tailwind CSS 4 + shadcn/ui. Includes layout components, pages (home, 404, error, loading), hooks, types, and documentation.
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
import { siteConfig } from "@/lib/site"
|
||||
|
||||
export function Footer() {
|
||||
return (
|
||||
<footer className="border-t">
|
||||
<div className="mx-auto flex h-14 max-w-5xl items-center justify-between px-4">
|
||||
<p className="text-sm text-muted-foreground">
|
||||
© {new Date().getFullYear()} {siteConfig.name}
|
||||
</p>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Built with{" "}
|
||||
<a
|
||||
href="https://nextjs.org"
|
||||
className="underline underline-offset-4 hover:text-foreground"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
Next.js
|
||||
</a>{" "}
|
||||
and{" "}
|
||||
<a
|
||||
href="https://ui.shadcn.com"
|
||||
className="underline underline-offset-4 hover:text-foreground"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
shadcn/ui
|
||||
</a>
|
||||
</p>
|
||||
</div>
|
||||
</footer>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
import Link from "next/link"
|
||||
|
||||
import { siteConfig, navLinks } from "@/lib/site"
|
||||
import { buttonVariants } from "@/components/ui/button"
|
||||
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"
|
||||
import { Menu } from "lucide-react"
|
||||
|
||||
function DesktopNav() {
|
||||
return (
|
||||
<nav className="hidden gap-6 md:flex" aria-label="Main navigation">
|
||||
{navLinks.map((item) => (
|
||||
<Link
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
className="text-sm font-medium text-muted-foreground transition-colors hover:text-foreground"
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
)
|
||||
}
|
||||
|
||||
function MobileNav() {
|
||||
return (
|
||||
<Sheet>
|
||||
<SheetTrigger
|
||||
className={buttonVariants({ variant: "outline", size: "icon" }) + " md:hidden"}
|
||||
aria-label="Open menu"
|
||||
>
|
||||
<Menu className="size-5" />
|
||||
</SheetTrigger>
|
||||
<SheetContent side="right">
|
||||
<nav className="mt-8 flex flex-col gap-4" aria-label="Mobile navigation">
|
||||
{navLinks.map((item) => (
|
||||
<Link
|
||||
key={item.href}
|
||||
href={item.href}
|
||||
className="text-base font-medium text-muted-foreground transition-colors hover:text-foreground"
|
||||
>
|
||||
{item.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
)
|
||||
}
|
||||
|
||||
export function Header() {
|
||||
return (
|
||||
<header className="sticky top-0 z-50 border-b bg-background/95 backdrop-blur-sm supports-backdrop-filter:bg-background/60">
|
||||
<div className="mx-auto flex h-14 max-w-5xl items-center justify-between px-4">
|
||||
<Link href="/" className="text-lg font-semibold tracking-tight">
|
||||
{siteConfig.name}
|
||||
</Link>
|
||||
<DesktopNav />
|
||||
<MobileNav />
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export { Header } from "./header"
|
||||
export { Footer } from "./footer"
|
||||
Reference in New Issue
Block a user