- Added styles for WordPress table and button blocks in globals.css. - Updated layout.tsx to include a favicon. - Improved blog page layout and search functionality, including new search and filter icons. - Implemented related posts feature in blog post pages with new BlogBlockquote and BlogPullquote components. - Enhanced blog card display with a new variant for smaller cards. - Updated blog collapse sections for better user interaction. - Added new utility functions for extracting block data from WordPress content.
114 lines
6.4 KiB
TypeScript
114 lines
6.4 KiB
TypeScript
'use client'
|
|
import Link from 'next/link'
|
|
import { usePathname } from 'next/navigation'
|
|
import { Logo } from '@/components/logo'
|
|
import { Menu, X } from 'lucide-react'
|
|
import { Button } from '@/components/ui/button'
|
|
import React from 'react'
|
|
import { cn } from '@/lib/utils'
|
|
import { ThemeToggle } from '@/components/theme-toggle'
|
|
|
|
const menuItems = [
|
|
{ name: 'صفحه اصلی', href: '/' },
|
|
{ name: 'بلاگ', href: '/blog' },
|
|
{ name: 'راه حلها', href: '/solutions' },
|
|
// { name: 'قیمتگذاری', href: '/pricing' },
|
|
{ name: 'درباره ما', href: '/about' },
|
|
]
|
|
|
|
function isLinkActive(pathname: string, href: string): boolean {
|
|
if (href === '/') return pathname === '/'
|
|
return pathname === href || pathname.startsWith(href + '/')
|
|
}
|
|
|
|
export const HeroHeader = () => {
|
|
const pathname = usePathname()
|
|
const [menuState, setMenuState] = React.useState(false)
|
|
const [isScrolled, setIsScrolled] = React.useState(false)
|
|
|
|
React.useEffect(() => {
|
|
const handleScroll = () => {
|
|
setIsScrolled(window.scrollY > 50)
|
|
}
|
|
window.addEventListener('scroll', handleScroll)
|
|
return () => window.removeEventListener('scroll', handleScroll)
|
|
}, [])
|
|
return (
|
|
<header>
|
|
<nav
|
|
data-state={menuState && 'active'}
|
|
className="fixed z-20 w-full px-2">
|
|
<div className={cn('mx-auto mt-2 max-w-6xl px-6 transition-all duration-300 lg:px-12 bg-background/80 backdrop-blur-md rounded-2xl border border-border/50', isScrolled && 'bg-background/95 max-w-4xl shadow-lg lg:px-5')}>
|
|
<div className="relative flex flex-wrap items-center justify-between gap-6 py-2 lg:gap-0 lg:py-3">
|
|
<div className="flex w-full justify-between lg:w-auto">
|
|
<Logo />
|
|
<button
|
|
onClick={() => setMenuState(!menuState)}
|
|
aria-label={menuState == true ? 'بستن منو' : 'باز کردن منو'}
|
|
className="relative z-20 -m-2.5 -mr-4 block cursor-pointer p-2.5 lg:hidden">
|
|
<Menu className="in-data-[state=active]:rotate-180 in-data-[state=active]:scale-0 in-data-[state=active]:opacity-0 m-auto size-6 duration-200" />
|
|
<X className="in-data-[state=active]:rotate-0 in-data-[state=active]:scale-100 in-data-[state=active]:opacity-100 absolute inset-0 m-auto size-6 -rotate-180 scale-0 opacity-0 duration-200" />
|
|
</button>
|
|
</div>
|
|
|
|
<div className="absolute inset-0 m-auto hidden size-fit lg:flex items-center gap-8">
|
|
<ul className="flex gap-8 text-sm">
|
|
{menuItems.map((item, index) => {
|
|
const active = isLinkActive(pathname ?? '', item.href)
|
|
return (
|
|
<li key={index}>
|
|
<Link
|
|
href={item.href}
|
|
className={cn(
|
|
'text-muted-foreground hover:text-foreground transition-all duration-300 relative group',
|
|
active && 'text-foreground'
|
|
)}>
|
|
<span className="relative z-10">{item.name}</span>
|
|
<span className={cn(
|
|
'absolute bottom-0 right-0 h-0.5 bg-accent transition-all duration-300 group-hover:w-full',
|
|
active ? 'w-full' : 'w-0'
|
|
)} />
|
|
</Link>
|
|
</li>
|
|
)
|
|
})}
|
|
</ul>
|
|
<ThemeToggle />
|
|
</div>
|
|
|
|
<div className="bg-background in-data-[state=active]:block lg:in-data-[state=active]:flex mb-6 hidden w-full flex-wrap items-center justify-end space-y-8 rounded-3xl border p-6 shadow-2xl shadow-zinc-300/20 md:flex-nowrap lg:m-0 lg:flex lg:w-fit lg:gap-6 lg:space-y-0 lg:border-transparent lg:bg-transparent lg:p-0 lg:shadow-none dark:shadow-none dark:lg:bg-transparent">
|
|
<div className="lg:hidden w-full">
|
|
<ul className="space-y-6 text-base">
|
|
{menuItems.map((item, index) => {
|
|
const active = isLinkActive(pathname ?? '', item.href)
|
|
return (
|
|
<li key={index}>
|
|
<Link
|
|
href={item.href}
|
|
className={cn(
|
|
'text-muted-foreground hover:text-foreground transition-all duration-300 relative group block',
|
|
active && 'text-foreground'
|
|
)}>
|
|
<span className="relative z-10">{item.name}</span>
|
|
<span className={cn(
|
|
'absolute bottom-0 right-0 h-0.5 bg-accent transition-all duration-300 group-hover:w-full',
|
|
active ? 'w-full' : 'w-0'
|
|
)} />
|
|
</Link>
|
|
</li>
|
|
)
|
|
})}
|
|
</ul>
|
|
<div className="mt-6 flex justify-end">
|
|
<ThemeToggle />
|
|
</div>
|
|
</div>
|
|
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</nav>
|
|
</header>
|
|
)
|
|
}
|