实现响应式导航栏组件
This commit is contained in:
@@ -8,7 +8,7 @@ import banner from '@/assets/header/help/banner.webp'
|
||||
|
||||
export default function HelpMenu() {
|
||||
return (
|
||||
<Wrap className="w-full grid grid-cols-4 gap-4 justify-items-center h-75">
|
||||
<Wrap className="w-full grid grid-cols-3 lg:grid-cols-4 gap-4 justify-items-start">
|
||||
<Column
|
||||
icon={h01}
|
||||
title="提取IP"
|
||||
@@ -35,7 +35,7 @@ export default function HelpMenu() {
|
||||
{lead: '行业资讯', href: '#'},
|
||||
]}
|
||||
/>
|
||||
<Image src={banner} alt="banner" className=""/>
|
||||
<Image src={banner} alt="banner" className="hidden lg:block"/>
|
||||
</Wrap>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export function LinkItem(props: {
|
||||
href: string
|
||||
}) {
|
||||
return (
|
||||
<li className="group relative">
|
||||
<li className="group relative flex-none">
|
||||
<Link
|
||||
href={props.href}
|
||||
className={[
|
||||
@@ -36,7 +36,7 @@ export function MenuItem(props: {
|
||||
onTouchStart?: (e: React.TouchEvent) => void
|
||||
}) {
|
||||
return (
|
||||
<li className="group relative">
|
||||
<li className="group relative flex-none">
|
||||
<button
|
||||
onPointerEnter={props.onEnter}
|
||||
onPointerLeave={props.onLeave}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import {ReactNode, useContext, useState, useEffect} from 'react'
|
||||
import {ReactNode, useState, useEffect, MouseEvent} from 'react'
|
||||
import Wrap from '@/components/wrap'
|
||||
import Image from 'next/image'
|
||||
import anno from '@/assets/header/product/anno.svg'
|
||||
@@ -7,7 +7,6 @@ import Link from 'next/link'
|
||||
import {merge} from '@/lib/utils'
|
||||
import prod from '@/assets/header/product/prod.svg'
|
||||
import custom from '@/assets/header/product/custom.svg'
|
||||
import {HeaderContext} from '@/app/(home)/@header/_client/provider'
|
||||
import {useSearchParams} from 'next/navigation'
|
||||
import {useRouter} from 'next/navigation'
|
||||
|
||||
@@ -18,8 +17,6 @@ export function Tab(props: {
|
||||
onSelect: () => void
|
||||
children: ReactNode
|
||||
}) {
|
||||
const searchParams = useSearchParams()
|
||||
const currentType = searchParams?.get('type') || 'short'
|
||||
return (
|
||||
<li role="tab">
|
||||
<button
|
||||
@@ -35,6 +32,53 @@ export function Tab(props: {
|
||||
)
|
||||
}
|
||||
|
||||
export default function ProductMenu() {
|
||||
const [type, setType] = useState<TabType>('domestic')
|
||||
|
||||
useEffect(() => {
|
||||
const checkMobile = () => {
|
||||
}
|
||||
|
||||
checkMobile()
|
||||
window.addEventListener('resize', checkMobile)
|
||||
return () => window.removeEventListener('resize', checkMobile)
|
||||
}, [])
|
||||
return (
|
||||
<Wrap className="flex">
|
||||
<ul role="tablist" className="w-48">
|
||||
<Tab selected={type === 'domestic'} onSelect={() => setType('domestic')}>国内代理</Tab>
|
||||
<Tab selected={type === 'oversea'} onSelect={() => setType('oversea')}>海外代理</Tab>
|
||||
</ul>
|
||||
<div className="flex-1">
|
||||
{type === 'domestic'
|
||||
? (
|
||||
<Domestic/>
|
||||
) : (
|
||||
<Oversea/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<aside className="hidden w-64 lg:block">
|
||||
<h3 className="flex gap-3 items-center mb-4">
|
||||
<Image src={anno} alt="公告" className="w-10 h-10"/>
|
||||
<span>网站公告</span>
|
||||
</h3>
|
||||
<div className="flex flex-col gap-2">
|
||||
<p>官网最新上线,体验再升级!</p>
|
||||
<p className="text-gray-400 text-sm">
|
||||
1.新增多样使用功能,新增多样使用
|
||||
新增多样使用功能
|
||||
</p>
|
||||
<p className="text-gray-400 text-sm">
|
||||
2.新增多样使用功能,新增多样使用
|
||||
新增多样使用功能
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
</Wrap>
|
||||
)
|
||||
}
|
||||
|
||||
export function Domestic(props: {}) {
|
||||
const searchParams = useSearchParams()
|
||||
const currentType = searchParams?.get('type') || 'short'
|
||||
@@ -86,69 +130,6 @@ export function Domestic(props: {}) {
|
||||
)
|
||||
}
|
||||
|
||||
export function Oversea(props: {}) {
|
||||
return (
|
||||
<section role="tabpanel">
|
||||
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default function ProductMenu() {
|
||||
const [type, setType] = useState<TabType>('domestic')
|
||||
const searchParams = useSearchParams()
|
||||
useEffect(() => {
|
||||
const urlType = searchParams?.get('type')
|
||||
console.log('URL参数:', urlType)
|
||||
}, [searchParams])
|
||||
// 响应式布局
|
||||
const [isMobile, setIsMobile] = useState(false)
|
||||
|
||||
useEffect(() => {
|
||||
const checkMobile = () => {
|
||||
setIsMobile(window.innerWidth <= 1024)
|
||||
}
|
||||
|
||||
checkMobile()
|
||||
window.addEventListener('resize', checkMobile)
|
||||
return () => window.removeEventListener('resize', checkMobile)
|
||||
}, [])
|
||||
return (
|
||||
<Wrap className="flex h-75">
|
||||
<ul role="tablist" className="w-48">
|
||||
<Tab selected={type === 'domestic'} onSelect={() => setType('domestic')}>国内代理</Tab>
|
||||
<Tab selected={type === 'oversea'} onSelect={() => setType('oversea')}>海外代理</Tab>
|
||||
</ul>
|
||||
<div className="flex-1">
|
||||
{type === 'domestic'
|
||||
? (
|
||||
<Domestic/>
|
||||
) : (
|
||||
<Oversea/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
<aside className="w-64">
|
||||
<h3 className="flex gap-3 items-center mb-4">
|
||||
<Image src={anno} alt="公告" className="w-10 h-10"/>
|
||||
<span>网站公告</span>
|
||||
</h3>
|
||||
<div className="flex flex-col gap-2">
|
||||
<p>官网最新上线,体验再升级!</p>
|
||||
<p className="text-gray-400 text-sm">
|
||||
1.新增多样使用功能,新增多样使用
|
||||
新增多样使用功能
|
||||
</p>
|
||||
<p className="text-gray-400 text-sm">
|
||||
2.新增多样使用功能,新增多样使用
|
||||
新增多样使用功能
|
||||
</p>
|
||||
</div>
|
||||
</aside>
|
||||
</Wrap>
|
||||
)
|
||||
}
|
||||
|
||||
export function DomesticLink(props: {
|
||||
label: string
|
||||
desc: string
|
||||
@@ -156,22 +137,17 @@ export function DomesticLink(props: {
|
||||
discount: number
|
||||
active?: boolean
|
||||
}) {
|
||||
const ctx = useContext(HeaderContext)
|
||||
const router = useRouter()
|
||||
if (!ctx) {
|
||||
throw new Error(`HeaderContext not found`)
|
||||
}
|
||||
|
||||
// const onClick = () => {
|
||||
// ctx.setMenu(false)
|
||||
// const ctx = useContext(HeaderContext)
|
||||
// if (!ctx) {
|
||||
// throw new Error(`HeaderContext not found`)
|
||||
// }
|
||||
const onClick = (e: React.MouseEvent) => {
|
||||
|
||||
const onClick = (e: MouseEvent) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
ctx.setMenu(false)
|
||||
setTimeout(() => {
|
||||
router.push(props.href)
|
||||
}, ctx.isMobile ? 100 : 0)
|
||||
// ctx.setMenu(false)
|
||||
router.push(props.href)
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -197,3 +173,11 @@ export function DomesticLink(props: {
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
export function Oversea(props: {}) {
|
||||
return (
|
||||
<section role="tabpanel">
|
||||
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import HelpMenu from './help'
|
||||
import Wrap from '@/components/wrap'
|
||||
import logo from '@/assets/logo.webp'
|
||||
import {Button} from '@/components/ui/button'
|
||||
import {useProfileStore} from '@/components/providers/StoreProvider'
|
||||
import {useProfileStore} from '@/app/stores'
|
||||
import UserCenter from '@/components/composites/user-center'
|
||||
import {MenuIcon} from 'lucide-react'
|
||||
import {merge} from '@/lib/utils'
|
||||
@@ -26,7 +26,6 @@ export default function Provider(props: ProviderProps) {
|
||||
// 滚动条状态
|
||||
// ======================
|
||||
const [scroll, setScroll] = useState(false) // Changed to false for client-side rendering
|
||||
const [mobileMenuOpen, setMobileMenuOpen] = useState(false) // 控制移动端菜单展开/收起
|
||||
const handleScroll = useCallback(() => {
|
||||
setScroll(window.scrollY > 48)
|
||||
}, [])
|
||||
@@ -47,12 +46,8 @@ export default function Provider(props: ProviderProps) {
|
||||
const [menu, setMenu] = useState(false)
|
||||
const [page, setPage] = useState(0)
|
||||
const menuRef = useRef<HTMLDivElement>(null)
|
||||
// 屏幕1024时
|
||||
const [isMobile, setIsMobile] = useState(false)
|
||||
// 控制产品订购下拉菜单的展开/收起
|
||||
const [productDropdownOpen, setProductDropdownOpen] = useState(false)
|
||||
|
||||
// 点击外部关闭菜单
|
||||
useEffect(() => {
|
||||
const handleClickOutside = (e: MouseEvent | TouchEvent) => {
|
||||
if (menuRef.current && !menuRef.current.contains(e.target as Node)) {
|
||||
@@ -72,8 +67,13 @@ export default function Provider(props: ProviderProps) {
|
||||
}
|
||||
}, [])
|
||||
|
||||
const isMobile = () => {
|
||||
if (typeof window === 'undefined') return false
|
||||
return window.innerWidth <= 768
|
||||
}
|
||||
|
||||
const handleMenuEnter = (pageIndex: number) => {
|
||||
if (isMobile && menu && page === pageIndex) {
|
||||
if (isMobile() && menu && page === pageIndex) {
|
||||
setMenu(false)
|
||||
}
|
||||
else {
|
||||
@@ -82,17 +82,22 @@ export default function Provider(props: ProviderProps) {
|
||||
}
|
||||
}
|
||||
|
||||
const handleMenuLeave = useCallback(() => {
|
||||
if (!isMobile) {
|
||||
const handleMenuLeave = () => {
|
||||
if (!isMobile()) {
|
||||
setMenu(false)
|
||||
}
|
||||
}, [isMobile])
|
||||
}
|
||||
|
||||
const pages = useMemo(() => [
|
||||
<ProductMenu key="product"/>,
|
||||
<SolutionMenu key="solution"/>,
|
||||
<HelpMenu key="help"/>,
|
||||
], [])
|
||||
|
||||
const toggleMobileMenu = () => {
|
||||
setMenu(!menu)
|
||||
}
|
||||
|
||||
// ======================
|
||||
// 用户信息
|
||||
// ======================
|
||||
@@ -103,43 +108,27 @@ export default function Provider(props: ProviderProps) {
|
||||
// render
|
||||
// ======================
|
||||
|
||||
// 屏幕1024时响应式处理
|
||||
useEffect(() => {
|
||||
const checkMobile = () => {
|
||||
const mobile = window.innerWidth <= 1024
|
||||
setIsMobile(mobile)
|
||||
// 移除自动关闭菜单的逻辑,让交互逻辑处理菜单状态
|
||||
}
|
||||
checkMobile()
|
||||
window.addEventListener('resize', checkMobile)
|
||||
return () => window.removeEventListener('resize', checkMobile)
|
||||
}, [])
|
||||
|
||||
// 切换移动菜单
|
||||
const toggleMobileMenu = () => {
|
||||
setMobileMenuOpen(!mobileMenuOpen)
|
||||
}
|
||||
return (
|
||||
<HeaderContext.Provider value={{setMenu, isMobile}}>
|
||||
<HeaderContext.Provider value={{setMenu, isMobile: isMobile()}}>
|
||||
<div
|
||||
ref={menuRef}
|
||||
className={[
|
||||
`transition-[background, shadow] duration-200 ease-in-out`,
|
||||
menu || mobileMenuOpen || productDropdownOpen
|
||||
menu
|
||||
? `bg-[#fffe] backdrop-blur-sm`
|
||||
: scroll
|
||||
? `bg-[#fffe] backdrop-blur-sm shadow-lg`
|
||||
: `bg-transparent shadow-none`,
|
||||
].join(' ')}>
|
||||
<Wrap className="h-20 flex justify-between items-center">
|
||||
<div className="flex justify-between items-center gap-2 lg:gap-8 h-9 lg:h-auto max-lg:flex-row-reverse lg:items-stretch">
|
||||
<Wrap className="h-14 lg:h-16 flex justify-between items-stretch">
|
||||
<div className="flex justify-between items-stretch gap-2 lg:gap-8 h-9 lg:h-auto max-lg:flex-row-reverse lg:items-stretch">
|
||||
{/* logo */}
|
||||
<Link href="/" className="flex items-center">
|
||||
<Image src={logo} alt="logo" height={40} className="translate-y-0.5"/>
|
||||
<Link href="/" className="self-center">
|
||||
<Image src={logo} alt="logo" height={36}/>
|
||||
</Link>
|
||||
|
||||
{/* 菜单 */}
|
||||
<nav className="flex flex-col items-center">
|
||||
<nav className="flex flex-col">
|
||||
<Button
|
||||
theme="ghost"
|
||||
className="w-9 h-9 lg:hidden"
|
||||
@@ -150,13 +139,8 @@ export default function Provider(props: ProviderProps) {
|
||||
</Button>
|
||||
<ul
|
||||
className={merge(
|
||||
'h-full items-stretch max-lg:h-auto relative',
|
||||
'max-lg:absolute max-lg:top-full max-lg:left-0 max-lg:w-screen',
|
||||
'max-lg:bg-[#fffe] max-lg:backdrop-blur-sm',
|
||||
mobileMenuOpen
|
||||
? 'max-lg:flex max-lg:flex-col max-lg:max-h-[500px] max-lg:py-4 max-lg:opacity-100'
|
||||
: 'max-lg:hidden max-lg:max-h-0 max-lg:py-0 max-lg:opacity-0',
|
||||
'lg:flex lg:items-stretch ',
|
||||
`h-full flex items-stretch`,
|
||||
'max-lg:absolute max-lg:top-full max-lg:left-0 max-lg:w-screen max-lg:h-12 max-lg:overflow-auto',
|
||||
)}
|
||||
>
|
||||
<LinkItem text="首页" href="/"/>
|
||||
@@ -167,34 +151,25 @@ export default function Provider(props: ProviderProps) {
|
||||
onEnter={() => handleMenuEnter(0)}
|
||||
onLeave={handleMenuLeave}
|
||||
onTouchStart={() => handleMenuEnter(0)}
|
||||
>
|
||||
{/* {!isMobile && !menu && <ProductMenu/>} */}
|
||||
</MenuItem>
|
||||
/>
|
||||
<MenuItem
|
||||
text="业务场景"
|
||||
active={menu && page === 1}
|
||||
onEnter={() => handleMenuEnter(1)}
|
||||
onLeave={handleMenuLeave}
|
||||
// onTouchStart={() => handleMenuEnter(1)}
|
||||
>
|
||||
{/* {!isMobile && !menu && <SolutionMenu/>} */}
|
||||
</MenuItem>
|
||||
/>
|
||||
<MenuItem
|
||||
text="帮助中心"
|
||||
active={menu && page === 2}
|
||||
onEnter={() => handleMenuEnter(2)}
|
||||
onLeave={handleMenuLeave}
|
||||
// onTouchStart={() => handleMenuEnter(2)}
|
||||
>
|
||||
{/* {!isMobile && !menu && <HelpMenu/>} */}
|
||||
</MenuItem>
|
||||
/>
|
||||
<LinkItem
|
||||
text="企业服务"
|
||||
href="#"/>
|
||||
<LinkItem
|
||||
text="推广返利"
|
||||
href="#"/>
|
||||
|
||||
</ul>
|
||||
</nav>
|
||||
</div>
|
||||
@@ -222,7 +197,7 @@ export default function Provider(props: ProviderProps) {
|
||||
</div>
|
||||
)
|
||||
: (
|
||||
<UserCenter/>
|
||||
<div></div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
@@ -234,16 +209,16 @@ export default function Provider(props: ProviderProps) {
|
||||
className={[
|
||||
`shadow-lg`,
|
||||
`overflow-hidden bg-[#fffe] backdrop-blur-sm`,
|
||||
`transition-all duration-200 ease-in-out`,
|
||||
`transition-[opacity,padding,height] transition-discrete duration-200 ease-in-out`,
|
||||
menu
|
||||
? `opacity-100 py-8 h-auto visible`
|
||||
: `opacity-0 py-0 h-0 invisible`,
|
||||
isMobile
|
||||
? `delay-[0s,0s,0s] opacity-100 py-8 h-auto`
|
||||
: `delay-[0s,0s,0.2s] opacity-0 py-0 h-0`,
|
||||
isMobile()
|
||||
? `max-lg:fixed max-lg:top-65 max-lg:left-0 max-lg:right-0 max-lg:w-full max-lg:z-[60] max-lg:overflow-y-auto max-lg:max-h-[calc(100vh-5rem)]`
|
||||
: `absolute top-full left-0 right-0`,
|
||||
].join(' ')}
|
||||
onPointerEnter={() => !isMobile && setMenu(true)}
|
||||
onPointerLeave={() => !isMobile && setMenu(false)}
|
||||
onPointerEnter={() => !isMobile() && setMenu(true)}
|
||||
onPointerLeave={() => !isMobile() && setMenu(false)}
|
||||
>
|
||||
{pages[page]}
|
||||
</div>
|
||||
|
||||
@@ -12,7 +12,7 @@ import {StaticImageData} from 'next/image'
|
||||
|
||||
export default function SolutionMenu() {
|
||||
return (
|
||||
<Wrap className="grid grid-cols-4 auto-rows-fr gap-4 h-75">
|
||||
<Wrap className="grid grid-cols-2 lg:grid-cols-4 lg:auto-rows-fr gap-4">
|
||||
<SolutionItem
|
||||
icon={s01}
|
||||
title="数据抓取"
|
||||
@@ -65,7 +65,7 @@ function SolutionItem(props: {
|
||||
return (
|
||||
<div
|
||||
className={[
|
||||
`h-full p-4 flex gap-4 items-start rounded-md cursor-pointer`,
|
||||
`h-full lg:p-4 flex gap-4 items-start rounded-md cursor-pointer`,
|
||||
`transition-colors duration-200 hover:bg-blue-50`,
|
||||
].join(' ')}
|
||||
>
|
||||
|
||||
@@ -1,11 +1,154 @@
|
||||
import Provider from '@/app/(home)/@header/_client/provider'
|
||||
'use client'
|
||||
import UserCenter from '@/components/composites/user-center'
|
||||
import {useClientStore, useProfileStore} from '@/app/stores'
|
||||
import {buttonVariants} from '@/components/ui/button'
|
||||
import {
|
||||
Navigation,
|
||||
NavigationIndicator,
|
||||
NavigationLink,
|
||||
NavigationLinkItem,
|
||||
NavigationGroup,
|
||||
NavigationTriggerItem,
|
||||
NavigationMenuViewport,
|
||||
} from '@/components/ui/navigation-menu'
|
||||
import Wrap from '@/components/wrap'
|
||||
import {merge} from '@/lib/utils'
|
||||
import {useState, useCallback, useEffect, useContext} from 'react'
|
||||
import Image from 'next/image'
|
||||
import logo from '@/assets/logo.webp'
|
||||
import ProductMenu, {Domestic} from '@/app/(home)/@header/_client/product'
|
||||
import SolutionMenu from '@/app/(home)/@header/_client/solution'
|
||||
import HelpMenu from '@/app/(home)/@header/_client/help'
|
||||
import {MenuIcon} from 'lucide-react'
|
||||
|
||||
export type HeaderProps = {}
|
||||
|
||||
export default async function Header(props: HeaderProps) {
|
||||
export default function Header(props: HeaderProps) {
|
||||
// ======================
|
||||
// 背景显示状态
|
||||
// ======================
|
||||
|
||||
const [expand, setExpand] = useState(false)
|
||||
const [scroll, setScroll] = useState(false)
|
||||
const handleScroll = useCallback(() => {
|
||||
setScroll(window.scrollY > 48)
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
setScroll(window.scrollY > 48)
|
||||
window.addEventListener('scroll', handleScroll)
|
||||
return () => {
|
||||
window.removeEventListener('scroll', handleScroll)
|
||||
}
|
||||
}, [handleScroll])
|
||||
|
||||
// ======================
|
||||
// 移动端
|
||||
// ======================
|
||||
|
||||
const lg = useClientStore(state => state.breakpoint.lg)
|
||||
|
||||
// ======================
|
||||
// render
|
||||
// ======================
|
||||
|
||||
return (
|
||||
<header className="fixed top-0 w-full z-10">
|
||||
<Provider/>
|
||||
<header
|
||||
data-expand={expand}
|
||||
data-scroll={scroll}
|
||||
data-effect={expand || scroll}
|
||||
className="group/header w-full fixed left-0 top-0 z-20"
|
||||
>
|
||||
<Navigation
|
||||
onValueChange={(value) => {
|
||||
setExpand(!!value)
|
||||
}}
|
||||
>
|
||||
<div className={merge(
|
||||
`transition-[background-color,backdrop-filter,box-shadow] duration-200 ease-in-out`,
|
||||
`bg-transparent backdrop-blur-none shadow-none`,
|
||||
`group-data-[effect=true]/header:bg-card/90`,
|
||||
`group-data-[effect=true]/header:backdrop-blur-sm`,
|
||||
`group-data-[scroll=true]/header:shadow-lg`,
|
||||
)}>
|
||||
<Wrap className={merge('h-14 md:h-16 flex justify-between items-stretch')}>
|
||||
<div className="flex items-stretch lg:flex-row-reverse">
|
||||
{lg ? (
|
||||
<NavigationGroup className="gap-0 flex">
|
||||
<NavigationLinkItem href="/" text="首页"/>
|
||||
|
||||
<NavigationTriggerItem text="产品订购" className="h-80">
|
||||
<ProductMenu/>
|
||||
</NavigationTriggerItem>
|
||||
|
||||
<NavigationTriggerItem text="业务场景" className="h-80">
|
||||
<SolutionMenu/>
|
||||
</NavigationTriggerItem>
|
||||
|
||||
<NavigationTriggerItem text="帮助中心" className="h-80">
|
||||
<HelpMenu/>
|
||||
</NavigationTriggerItem>
|
||||
|
||||
<NavigationLinkItem href="/" text="企业服务"/>
|
||||
<NavigationLinkItem href="/" text="推广返利"/>
|
||||
|
||||
<NavigationIndicator/>
|
||||
</NavigationGroup>
|
||||
) : (
|
||||
<NavigationGroup className="flex">
|
||||
<NavigationTriggerItem
|
||||
suffix={false}
|
||||
text={<MenuIcon/>}
|
||||
className={merge(
|
||||
`flex flex-col items-start gap-6`,
|
||||
)}
|
||||
>
|
||||
<ProductMenu/>
|
||||
|
||||
<SolutionMenu/>
|
||||
|
||||
<HelpMenu/>
|
||||
|
||||
<NavigationLink href="/" text="企业服务"/>
|
||||
<NavigationLink href="/" text="推广返利"/>
|
||||
</NavigationTriggerItem>
|
||||
</NavigationGroup>
|
||||
)}
|
||||
|
||||
<NavigationLink href="/" text={<Image src={logo} alt="logo" height={36}/>}/>
|
||||
</div>
|
||||
<AccountRegion/>
|
||||
</Wrap>
|
||||
</div>
|
||||
|
||||
<NavigationMenuViewport className={merge(
|
||||
`bg-card/90 backdrop-blur-sm shadow-lg`,
|
||||
`transition-[padding,opacity,max-height]`,
|
||||
`group-data-[expand=false]/header:delay-[0s,0s,0.2s] group-data-[expand=true]/header:delay-0`,
|
||||
`p-0 group-data-[expand=true]/header:py-4`,
|
||||
`opacity-0 group-data-[effect=true]/header:opacity-100`,
|
||||
`max-h-0 group-data-[effect=true]/header:max-h-[calc(100vh-56px)] overflow-auto`,
|
||||
)}/>
|
||||
</Navigation>
|
||||
</header>
|
||||
)
|
||||
}
|
||||
|
||||
function AccountRegion() {
|
||||
const profile = useProfileStore(state => state.profile)
|
||||
|
||||
return (
|
||||
<div className="self-center">
|
||||
{profile ? (
|
||||
<UserCenter profile={profile}/>
|
||||
) : (
|
||||
<NavigationLink
|
||||
href="/login"
|
||||
text="登录 / 注册"
|
||||
classNameOverride={buttonVariants({
|
||||
theme: 'gradient',
|
||||
className: 'h-10 lg:h-12',
|
||||
})}/>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user