feat: 添加连锁门店系统首页及核心UI组件
新增首页布局、导航栏、页脚及多个核心UI组件(按钮、卡片、表格等) 添加图片资源、工具函数和样式配置 实现响应式设计和主题支持 包含行业解决方案展示区块
This commit is contained in:
150
components/navbar.tsx
Normal file
150
components/navbar.tsx
Normal file
@@ -0,0 +1,150 @@
|
||||
"use client"
|
||||
|
||||
import { useState, useEffect } from "react"
|
||||
import Link from "next/link"
|
||||
import { Button } from "@/components/ui/button"
|
||||
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"
|
||||
import { Menu, X } from "lucide-react"
|
||||
import { cn } from "@/lib/utils"
|
||||
import siteData from "@/data/site.json"
|
||||
|
||||
export function Navbar() {
|
||||
const [scrolled, setScrolled] = useState(false)
|
||||
const [open, setOpen] = useState(false)
|
||||
const { company, nav } = siteData
|
||||
|
||||
useEffect(() => {
|
||||
const onScroll = () => setScrolled(window.scrollY > 40)
|
||||
window.addEventListener("scroll", onScroll, { passive: true })
|
||||
return () => window.removeEventListener("scroll", onScroll)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<header
|
||||
className={cn(
|
||||
"fixed top-0 left-0 right-0 z-50 transition-all duration-500",
|
||||
scrolled
|
||||
? "bg-white/95 backdrop-blur-md shadow-sm border-b border-border"
|
||||
: "bg-transparent"
|
||||
)}
|
||||
>
|
||||
<div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div className="flex items-center justify-between h-16 lg:h-20">
|
||||
|
||||
{/* Logo */}
|
||||
<Link href="#home" className="flex flex-col leading-none group shrink-0">
|
||||
<div className="flex flex-col gap-0.5">
|
||||
<span className={cn(
|
||||
"font-bold text-base tracking-tight transition-colors duration-300",
|
||||
scrolled ? "text-foreground" : "text-white"
|
||||
)}>
|
||||
{company.name}
|
||||
</span>
|
||||
<span className={cn(
|
||||
"text-[10px] tracking-widest transition-colors duration-300",
|
||||
scrolled ? "text-muted-foreground" : "text-white/60"
|
||||
)}>
|
||||
{company.nameEn.toUpperCase()}
|
||||
</span>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* Desktop Nav */}
|
||||
<nav className="hidden lg:flex items-center gap-1" aria-label="主导航">
|
||||
{nav.links.map((link) => (
|
||||
<Link
|
||||
key={link.label}
|
||||
href={link.href}
|
||||
className={cn(
|
||||
"px-4 py-2 rounded-md text-sm font-medium transition-colors duration-200",
|
||||
scrolled
|
||||
? "text-muted-foreground hover:text-foreground hover:bg-muted"
|
||||
: "text-white/80 hover:text-white hover:bg-white/10"
|
||||
)}
|
||||
>
|
||||
{link.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
|
||||
{/* CTA */}
|
||||
<div className="hidden lg:flex items-center gap-3">
|
||||
<Button
|
||||
asChild
|
||||
size="sm"
|
||||
className={cn(
|
||||
"px-5 h-9 text-sm font-semibold shadow-sm transition-all duration-300",
|
||||
scrolled
|
||||
? "bg-primary hover:bg-primary-dark text-white"
|
||||
: "bg-white text-primary hover:bg-white/90"
|
||||
)}
|
||||
>
|
||||
<Link href="#contact">{nav.cta}</Link>
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* Mobile Menu */}
|
||||
<div className="lg:hidden">
|
||||
<Sheet open={open} onOpenChange={setOpen}>
|
||||
<SheetTrigger asChild>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="icon"
|
||||
className={cn(
|
||||
"transition-colors",
|
||||
scrolled ? "text-foreground" : "text-white hover:bg-white/10"
|
||||
)}
|
||||
aria-label="打开菜单"
|
||||
>
|
||||
<Menu className="w-5 h-5" />
|
||||
</Button>
|
||||
</SheetTrigger>
|
||||
<SheetContent side="right" className="w-72 p-0">
|
||||
<div className="flex flex-col h-full">
|
||||
<div className="flex items-center justify-between p-5 border-b border-border">
|
||||
<div className="flex flex-col leading-none gap-1">
|
||||
<span className="font-bold text-base text-foreground">{company.name}</span>
|
||||
<span className="text-[10px] tracking-widest text-muted-foreground">
|
||||
{company.nameEn.toUpperCase()}
|
||||
</span>
|
||||
</div>
|
||||
<button
|
||||
onClick={() => setOpen(false)}
|
||||
className="text-muted-foreground hover:text-foreground transition-colors"
|
||||
aria-label="关闭菜单"
|
||||
>
|
||||
<X className="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
<nav className="flex flex-col p-4 gap-1 flex-1" aria-label="移动端导航">
|
||||
{nav.links.map((link) => (
|
||||
<Link
|
||||
key={link.label}
|
||||
href={link.href}
|
||||
onClick={() => setOpen(false)}
|
||||
className="px-4 py-3 rounded-md text-sm font-medium text-foreground hover:bg-muted transition-colors"
|
||||
>
|
||||
{link.label}
|
||||
</Link>
|
||||
))}
|
||||
</nav>
|
||||
<div className="p-4 border-t border-border">
|
||||
<Button
|
||||
asChild
|
||||
className="w-full bg-primary hover:bg-primary-dark text-white"
|
||||
>
|
||||
<Link href="#contact" onClick={() => setOpen(false)}>
|
||||
{nav.cta}
|
||||
</Link>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</SheetContent>
|
||||
</Sheet>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user