x
This commit is contained in:
1 parent
943fd8f1a3
commit
9237c0eded
7 files changed
+776
-377
No files matched your search
@@ -265,9 +265,16 @@ export default function Navbar({ categories = [], initialMenu = [], settings = n
|
||||
|
||||
const isTwoTier = settings?.headerStyle === 'two_tier'
|
||||
|
||||
const showSearch = (settings?.themeTokens as any)?.headerShowSearch ?? (settings as any)?.headerShowSearch ?? true
|
||||
const showWishlist = (settings?.themeTokens as any)?.headerShowWishlist ?? (settings as any)?.headerShowWishlist ?? true
|
||||
const showCart = (settings?.themeTokens as any)?.headerShowCart ?? (settings as any)?.headerShowCart ?? true
|
||||
const showTrackOrder = (settings?.themeTokens as any)?.headerShowTrackOrder ?? (settings as any)?.headerShowTrackOrder ?? true
|
||||
const showLanguage = (settings?.themeTokens as any)?.headerShowLanguage ?? (settings as any)?.headerShowLanguage ?? true
|
||||
const showAccount = (settings?.themeTokens as any)?.headerShowAccount ?? (settings as any)?.headerShowAccount ?? true
|
||||
|
||||
const renderMobileActionButtons = (includeSearch = true) => (
|
||||
<div className="flex items-center gap-1.5 shrink-0">
|
||||
{includeSearch && (
|
||||
{includeSearch && showSearch && (
|
||||
<button
|
||||
onClick={() => {
|
||||
setSearchOpen(true)
|
||||
@@ -280,45 +287,51 @@ export default function Navbar({ categories = [], initialMenu = [], settings = n
|
||||
</button>
|
||||
)}
|
||||
|
||||
<Link
|
||||
href="/wishlist"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Wishlist"
|
||||
>
|
||||
<Heart className="h-4 w-4 transition-colors" />
|
||||
{wishlistCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{wishlistCount}
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
{showWishlist && (
|
||||
<Link
|
||||
href="/wishlist"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Wishlist"
|
||||
>
|
||||
<Heart className="h-4 w-4 transition-colors" />
|
||||
{wishlistCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{wishlistCount}
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
)}
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
toggleCart(true)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Cart"
|
||||
>
|
||||
<ShoppingBag className="h-4 w-4 transition-colors" />
|
||||
{cartCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{cartCount}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
{showCart && (
|
||||
<button
|
||||
onClick={() => {
|
||||
toggleCart(true)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Cart"
|
||||
>
|
||||
<ShoppingBag className="h-4 w-4 transition-colors" />
|
||||
{cartCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{cartCount}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
||||
<Link
|
||||
href="/track"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={iconButtonClass}
|
||||
aria-label={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
title={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
>
|
||||
<Truck className="h-4 w-4 transition-colors" />
|
||||
</Link>
|
||||
{showTrackOrder && (
|
||||
<Link
|
||||
href="/track"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={iconButtonClass}
|
||||
aria-label={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
title={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
>
|
||||
<Truck className="h-4 w-4 transition-colors" />
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -451,231 +464,67 @@ export default function Navbar({ categories = [], initialMenu = [], settings = n
|
||||
</div>
|
||||
|
||||
<div className="flex items-center justify-end gap-1.5 md:gap-2">
|
||||
<button
|
||||
onClick={() => {
|
||||
setSearchOpen(true)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
className={iconButtonClass}
|
||||
aria-label="Search"
|
||||
>
|
||||
<Search className="h-4 w-4 transition-colors" />
|
||||
</button>
|
||||
|
||||
<Link
|
||||
href="/wishlist"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Wishlist"
|
||||
>
|
||||
<Heart className="h-4 w-4 transition-colors" />
|
||||
{wishlistCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{wishlistCount}
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
toggleCart(true)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Cart"
|
||||
>
|
||||
<ShoppingBag className="h-4 w-4 transition-colors" />
|
||||
{cartCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{cartCount}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
|
||||
<Link
|
||||
href="/track"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
title={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
>
|
||||
<Truck className="h-4 w-4 transition-colors" />
|
||||
</Link>
|
||||
|
||||
<div className="hidden md:flex group relative items-center">
|
||||
<button className="ui-nav-chip">
|
||||
<Globe className="h-3.5 w-3.5" strokeWidth={1.5} />
|
||||
{activeLanguage.short}
|
||||
{showSearch && (
|
||||
<button
|
||||
onClick={() => {
|
||||
setSearchOpen(true)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
className={iconButtonClass}
|
||||
aria-label="Search"
|
||||
>
|
||||
<Search className="h-4 w-4 transition-colors" />
|
||||
</button>
|
||||
<div className="pointer-events-none absolute right-0 top-full w-36 pt-2 opacity-0 transition-all duration-300 group-hover:pointer-events-auto group-hover:opacity-100">
|
||||
<div className="ui-nav-panel space-y-0.5 p-1.5">
|
||||
{LANGUAGES.map((language) => {
|
||||
const isActive = lang.startsWith(language.code) || language.code.startsWith(lang)
|
||||
return (
|
||||
<button
|
||||
key={language.code}
|
||||
onClick={() => changeLanguage(language.code)}
|
||||
className={`flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-xs font-medium transition-colors ${
|
||||
isActive ? 'bg-surface-page font-bold text-text-main' : 'text-text-main/65 hover:bg-surface-page hover:text-brand-primary'
|
||||
}`}
|
||||
>
|
||||
<span>{language.label}</span>
|
||||
{isActive && <Check className="h-3.5 w-3.5" />}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="hidden md:flex relative items-center">
|
||||
{customer ? (
|
||||
<Link href="/profile" className="ml-1">
|
||||
{customer.pictureUrl ? (
|
||||
<Image
|
||||
src={customer.pictureUrl}
|
||||
alt={customer.displayName || 'Profile'}
|
||||
width={36}
|
||||
height={36}
|
||||
unoptimized
|
||||
className="h-9 w-9 rounded-full border-2 border-brand-primary/30 object-cover"
|
||||
/>
|
||||
) : (
|
||||
<span className="flex h-9 w-9 items-center justify-center rounded-full border-2 border-brand-primary/30 text-text-main/65">
|
||||
<User className="h-4 w-4" />
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
) : (
|
||||
<button
|
||||
onClick={loginWithLine}
|
||||
className="ui-button-line ml-2"
|
||||
>
|
||||
{t('nav.login', 'เข้าสู่ระบบด้วย LINE')}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Tier: Centered Navigation (Desktop only) */}
|
||||
<div className={`hidden md:flex w-full items-center justify-between transition-all duration-300 ${
|
||||
scrolled ? 'py-0.5' : 'border-t border-black/5 pt-2 mt-1'
|
||||
}`}>
|
||||
<div className={`transition-all duration-300 ${scrolled ? 'w-auto opacity-100' : 'w-0 opacity-0 overflow-hidden'}`}>
|
||||
<Link href="/" className="ui-brand-wordmark text-sm font-bold tracking-widest">
|
||||
{settings?.logoUrl ? (
|
||||
<Image src={settings.logoUrl} alt={brandName} width={120} height={28} unoptimized className="h-6 w-auto object-contain" />
|
||||
) : (
|
||||
brandName
|
||||
)}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 justify-center">
|
||||
<DesktopMegaMenu items={menuItems} lang={lang} currentPath={pathname} />
|
||||
</div>
|
||||
|
||||
<div className={`flex items-center gap-1.5 transition-all duration-300 ${scrolled ? 'w-auto opacity-100 md:gap-2' : 'w-0 opacity-0 overflow-hidden'}`}>
|
||||
<button onClick={() => setSearchOpen(true)} className={iconButtonClass} aria-label="Search">
|
||||
<Search className="h-4 w-4" />
|
||||
</button>
|
||||
<Link href="/wishlist" className={`relative ${iconButtonClass}`} aria-label="Wishlist">
|
||||
<Heart className="h-4 w-4" />
|
||||
{wishlistCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{wishlistCount}
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
<button onClick={() => toggleCart(true)} className={`relative ${iconButtonClass}`} aria-label="Cart">
|
||||
<ShoppingBag className="h-4 w-4" />
|
||||
{cartCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{cartCount}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="hidden md:flex w-full items-center justify-between gap-4">
|
||||
<div className="flex shrink-0 items-center">
|
||||
<Link
|
||||
href="/"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className="ui-brand-wordmark"
|
||||
>
|
||||
{settings?.logoUrl ? (
|
||||
<Image src={settings.logoUrl} alt={brandName} width={160} height={40} unoptimized className="h-8 w-auto object-contain md:h-10" />
|
||||
) : (
|
||||
brandName
|
||||
)}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 justify-center">
|
||||
{canRenderDesktopMenu && (
|
||||
<DesktopMegaMenu items={menuItems} lang={lang} currentPath={pathname} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex shrink-0 items-center gap-1.5 md:gap-2">
|
||||
<button
|
||||
onClick={() => {
|
||||
setSearchOpen(true)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
className={iconButtonClass}
|
||||
aria-label="Search"
|
||||
>
|
||||
<Search className="h-4 w-4 transition-colors" />
|
||||
</button>
|
||||
|
||||
<Link
|
||||
href="/wishlist"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Wishlist"
|
||||
>
|
||||
<Heart className="h-4 w-4 transition-colors" />
|
||||
{wishlistCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{wishlistCount}
|
||||
</span>
|
||||
{showWishlist && (
|
||||
<Link
|
||||
href="/wishlist"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Wishlist"
|
||||
>
|
||||
<Heart className="h-4 w-4 transition-colors" />
|
||||
{wishlistCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{wishlistCount}
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
)}
|
||||
</Link>
|
||||
|
||||
<button
|
||||
onClick={() => {
|
||||
toggleCart(true)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Cart"
|
||||
>
|
||||
<ShoppingBag className="h-4 w-4 transition-colors" />
|
||||
{cartCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{cartCount}
|
||||
</span>
|
||||
{showCart && (
|
||||
<button
|
||||
onClick={() => {
|
||||
toggleCart(true)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Cart"
|
||||
>
|
||||
<ShoppingBag className="h-4 w-4 transition-colors" />
|
||||
{cartCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{cartCount}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</button>
|
||||
|
||||
<Link
|
||||
href="/track"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
title={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
>
|
||||
<Truck className="h-4 w-4 transition-colors" />
|
||||
</Link>
|
||||
{showTrackOrder && (
|
||||
<Link
|
||||
href="/track"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
title={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
>
|
||||
<Truck className="h-4 w-4 transition-colors" />
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{canRenderDesktopMenu && (
|
||||
<>
|
||||
<div className="group relative flex items-center">
|
||||
{showLanguage && (
|
||||
<div className="hidden md:flex group relative items-center">
|
||||
<button className="ui-nav-chip">
|
||||
<Globe className="h-3.5 w-3.5" strokeWidth={1.5} />
|
||||
{activeLanguage.short}
|
||||
@@ -700,8 +549,10 @@ export default function Navbar({ categories = [], initialMenu = [], settings = n
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="relative flex items-center">
|
||||
{showAccount && (
|
||||
<div className="hidden md:flex relative items-center">
|
||||
{customer ? (
|
||||
<Link href="/profile" className="ml-1">
|
||||
{customer.pictureUrl ? (
|
||||
@@ -728,6 +579,198 @@ export default function Navbar({ categories = [], initialMenu = [], settings = n
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Bottom Tier: Centered Navigation (Desktop only) */}
|
||||
<div className={`hidden md:flex w-full items-center justify-between transition-all duration-300 ${
|
||||
scrolled ? 'py-0.5' : 'border-t border-black/5 pt-2 mt-1'
|
||||
}`}>
|
||||
<div className={`transition-all duration-300 ${scrolled ? 'w-auto opacity-100' : 'w-0 opacity-0 overflow-hidden'}`}>
|
||||
<Link href="/" className="ui-brand-wordmark text-sm font-bold tracking-widest">
|
||||
{settings?.logoUrl ? (
|
||||
<Image src={settings.logoUrl} alt={brandName} width={120} height={28} unoptimized className="h-6 w-auto object-contain" />
|
||||
) : (
|
||||
brandName
|
||||
)}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 justify-center">
|
||||
<DesktopMegaMenu items={menuItems} lang={lang} currentPath={pathname} />
|
||||
</div>
|
||||
|
||||
<div className={`flex items-center gap-1.5 transition-all duration-300 ${scrolled ? 'w-auto opacity-100 md:gap-2' : 'w-0 opacity-0 overflow-hidden'}`}>
|
||||
{showSearch && (
|
||||
<button onClick={() => setSearchOpen(true)} className={iconButtonClass} aria-label="Search">
|
||||
<Search className="h-4 w-4" />
|
||||
</button>
|
||||
)}
|
||||
{showWishlist && (
|
||||
<Link href="/wishlist" className={`relative ${iconButtonClass}`} aria-label="Wishlist">
|
||||
<Heart className="h-4 w-4" />
|
||||
{wishlistCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{wishlistCount}
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
)}
|
||||
{showCart && (
|
||||
<button onClick={() => toggleCart(true)} className={`relative ${iconButtonClass}`} aria-label="Cart">
|
||||
<ShoppingBag className="h-4 w-4" />
|
||||
{cartCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{cartCount}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="hidden md:flex w-full items-center justify-between gap-4">
|
||||
<div className="flex shrink-0 items-center">
|
||||
<Link
|
||||
href="/"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className="ui-brand-wordmark"
|
||||
>
|
||||
{settings?.logoUrl ? (
|
||||
<Image src={settings.logoUrl} alt={brandName} width={160} height={40} unoptimized className="h-8 w-auto object-contain md:h-10" />
|
||||
) : (
|
||||
brandName
|
||||
)}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-1 justify-center">
|
||||
{canRenderDesktopMenu && (
|
||||
<DesktopMegaMenu items={menuItems} lang={lang} currentPath={pathname} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="flex shrink-0 items-center gap-1.5 md:gap-2">
|
||||
{showSearch && (
|
||||
<button
|
||||
onClick={() => {
|
||||
setSearchOpen(true)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
className={iconButtonClass}
|
||||
aria-label="Search"
|
||||
>
|
||||
<Search className="h-4 w-4 transition-colors" />
|
||||
</button>
|
||||
)}
|
||||
|
||||
{showWishlist && (
|
||||
<Link
|
||||
href="/wishlist"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Wishlist"
|
||||
>
|
||||
<Heart className="h-4 w-4 transition-colors" />
|
||||
{wishlistCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{wishlistCount}
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{showCart && (
|
||||
<button
|
||||
onClick={() => {
|
||||
toggleCart(true)
|
||||
setMobileOpen(false)
|
||||
}}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label="Cart"
|
||||
>
|
||||
<ShoppingBag className="h-4 w-4 transition-colors" />
|
||||
{cartCount > 0 && (
|
||||
<span className="absolute -right-1 -top-1 flex h-4 w-4 items-center justify-center rounded-full bg-brand-primary text-[9px] font-bold text-surface-card">
|
||||
{cartCount}
|
||||
</span>
|
||||
)}
|
||||
</button>
|
||||
)}
|
||||
|
||||
{showTrackOrder && (
|
||||
<Link
|
||||
href="/track"
|
||||
onClick={() => setMobileOpen(false)}
|
||||
className={`relative ${iconButtonClass}`}
|
||||
aria-label={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
title={t('nav.trackOrder', 'ติดตามคำสั่งซื้อ')}
|
||||
>
|
||||
<Truck className="h-4 w-4 transition-colors" />
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{canRenderDesktopMenu && (
|
||||
<>
|
||||
{showLanguage && (
|
||||
<div className="group relative flex items-center">
|
||||
<button className="ui-nav-chip">
|
||||
<Globe className="h-3.5 w-3.5" strokeWidth={1.5} />
|
||||
{activeLanguage.short}
|
||||
</button>
|
||||
<div className="pointer-events-none absolute right-0 top-full w-36 pt-2 opacity-0 transition-all duration-300 group-hover:pointer-events-auto group-hover:opacity-100">
|
||||
<div className="ui-nav-panel space-y-0.5 p-1.5">
|
||||
{LANGUAGES.map((language) => {
|
||||
const isActive = lang.startsWith(language.code) || language.code.startsWith(lang)
|
||||
return (
|
||||
<button
|
||||
key={language.code}
|
||||
onClick={() => changeLanguage(language.code)}
|
||||
className={`flex w-full items-center justify-between rounded-lg px-3 py-2.5 text-xs font-medium transition-colors ${
|
||||
isActive ? 'bg-surface-page font-bold text-text-main' : 'text-text-main/65 hover:bg-surface-page hover:text-brand-primary'
|
||||
}`}
|
||||
>
|
||||
<span>{language.label}</span>
|
||||
{isActive && <Check className="h-3.5 w-3.5" />}
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{showAccount && (
|
||||
<div className="relative flex items-center">
|
||||
{customer ? (
|
||||
<Link href="/profile" className="ml-1">
|
||||
{customer.pictureUrl ? (
|
||||
<Image
|
||||
src={customer.pictureUrl}
|
||||
alt={customer.displayName || 'Profile'}
|
||||
width={36}
|
||||
height={36}
|
||||
unoptimized
|
||||
className="h-9 w-9 rounded-full border-2 border-brand-primary/30 object-cover"
|
||||
/>
|
||||
) : (
|
||||
<span className="flex h-9 w-9 items-center justify-center rounded-full border-2 border-brand-primary/30 text-text-main/65">
|
||||
<User className="h-4 w-4" />
|
||||
</span>
|
||||
)}
|
||||
</Link>
|
||||
) : (
|
||||
<button
|
||||
onClick={loginWithLine}
|
||||
className="ui-button-line ml-2"
|
||||
>
|
||||
{t('nav.login', 'เข้าสู่ระบบด้วย LINE')}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -745,6 +788,10 @@ export default function Navbar({ categories = [], initialMenu = [], settings = n
|
||||
onOpenLang={() => setLangSheetOpen(true)}
|
||||
onLogin={loginWithLine}
|
||||
onLogout={logout}
|
||||
showLanguage={showLanguage}
|
||||
showAccount={showAccount}
|
||||
showTrackOrder={showTrackOrder}
|
||||
showCart={showCart}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ interface MobileDrawerProps {
|
||||
onOpenLang: () => void
|
||||
onLogin: () => void
|
||||
onLogout: () => void
|
||||
showLanguage?: boolean
|
||||
showAccount?: boolean
|
||||
showTrackOrder?: boolean
|
||||
showCart?: boolean
|
||||
}
|
||||
|
||||
export function MobileDrawer({
|
||||
@@ -31,6 +35,10 @@ export function MobileDrawer({
|
||||
onOpenLang,
|
||||
onLogin,
|
||||
onLogout,
|
||||
showLanguage = true,
|
||||
showAccount = true,
|
||||
showTrackOrder = true,
|
||||
showCart = true,
|
||||
}: MobileDrawerProps) {
|
||||
const [stack, setStack] = useState<MenuNode[]>([{ type: 'root', data: items, title: 'Menu' }])
|
||||
|
||||
@@ -81,18 +89,20 @@ export function MobileDrawer({
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{customerName && (
|
||||
{showAccount && customerName && (
|
||||
<div className="border-b border-text-main/10">
|
||||
<Link href="/profile" onClick={onClose} className={linkClass}>
|
||||
My Profile
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
<div className="border-b border-text-main/10">
|
||||
<Link href="/track" onClick={onClose} className={linkClass}>
|
||||
{lang === 'th' ? 'ติดตามคำสั่งซื้อ' : 'Track Order'}
|
||||
</Link>
|
||||
</div>
|
||||
{showTrackOrder && (
|
||||
<div className="border-b border-text-main/10">
|
||||
<Link href="/track" onClick={onClose} className={linkClass}>
|
||||
{lang === 'th' ? 'ติดตามคำสั่งซื้อ' : 'Track Order'}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -167,13 +177,15 @@ export function MobileDrawer({
|
||||
<div className="z-10 flex shrink-0 items-center justify-between border-b border-text-main/10 bg-surface-card px-6 py-5">
|
||||
<span className="text-sm font-bold uppercase tracking-widest text-text-main">Menu</span>
|
||||
<div className="flex items-center gap-3">
|
||||
<button
|
||||
onClick={onOpenLang}
|
||||
className="flex shrink-0 items-center gap-1 rounded-md border border-brand-primary/30 bg-surface-page px-2.5 py-1 text-[10px] font-bold uppercase text-brand-primary"
|
||||
>
|
||||
<Globe className="h-3 w-3" />
|
||||
{lang.toUpperCase()}
|
||||
</button>
|
||||
{showLanguage && (
|
||||
<button
|
||||
onClick={onOpenLang}
|
||||
className="flex shrink-0 items-center gap-1 rounded-md border border-brand-primary/30 bg-surface-page px-2.5 py-1 text-[10px] font-bold uppercase text-brand-primary"
|
||||
>
|
||||
<Globe className="h-3 w-3" />
|
||||
{lang.toUpperCase()}
|
||||
</button>
|
||||
)}
|
||||
<button onClick={onClose} className="rounded-full p-1.5 text-text-main/65 transition hover:bg-surface-page hover:text-brand-primary">
|
||||
<X className="h-5 w-5" />
|
||||
</button>
|
||||
@@ -215,14 +227,16 @@ export function MobileDrawer({
|
||||
</div>
|
||||
|
||||
<div className="z-10 shrink-0 space-y-3 border-t border-text-main/10 bg-surface-card px-6 pb-8 pt-6">
|
||||
<Link
|
||||
href="/shop"
|
||||
onClick={onClose}
|
||||
className="block w-full rounded-xl bg-text-main py-3.5 text-center text-xs font-bold uppercase tracking-widest text-surface-card shadow-sm transition-colors hover:bg-brand-primary"
|
||||
>
|
||||
Shop Now
|
||||
</Link>
|
||||
{customerName ? (
|
||||
{showCart && (
|
||||
<Link
|
||||
href="/shop"
|
||||
onClick={onClose}
|
||||
className="block w-full rounded-xl bg-text-main py-3.5 text-center text-xs font-bold uppercase tracking-widest text-surface-card shadow-sm transition-colors hover:bg-brand-primary"
|
||||
>
|
||||
Shop Now
|
||||
</Link>
|
||||
)}
|
||||
{showAccount && (customerName ? (
|
||||
<button
|
||||
onClick={() => {
|
||||
onLogout()
|
||||
@@ -242,7 +256,7 @@ export function MobileDrawer({
|
||||
>
|
||||
Login with LINE
|
||||
</button>
|
||||
)}
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in new issue
Block a user