Scrum4Me/components/mobile/mobile-tab-bar.tsx
Madhura68 47d57a0963 feat(ST-1134): MobileTabBar component (T-320)
Bottom-fixed nav-bar met 3 lucide-iconen (ListTree/Activity/Settings).
Verbergt Backlog/Solo-tabs als activeProductId null is.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-04 09:52:33 +02:00

68 lines
1.8 KiB
TypeScript

'use client'
import Link from 'next/link'
import { usePathname } from 'next/navigation'
import { ListTree, Activity, Settings } from 'lucide-react'
import { cn } from '@/lib/utils'
interface MobileTabBarProps {
activeProductId: string | null
}
export function MobileTabBar({ activeProductId }: MobileTabBarProps) {
const pathname = usePathname()
const tabs: Array<{ href: string; icon: typeof ListTree; label: string; match: (p: string) => boolean }> = []
if (activeProductId) {
tabs.push(
{
href: `/m/products/${activeProductId}`,
icon: ListTree,
label: 'Backlog',
match: (p) => p === `/m/products/${activeProductId}`,
},
{
href: `/m/products/${activeProductId}/solo`,
icon: Activity,
label: 'Solo',
match: (p) => p.startsWith(`/m/products/${activeProductId}/solo`),
},
)
}
tabs.push({
href: '/m/settings',
icon: Settings,
label: 'Settings',
match: (p) => p.startsWith('/m/settings'),
})
return (
<nav
aria-label="Hoofdnavigatie"
className="fixed bottom-0 left-0 right-0 z-40 flex border-t border-border bg-surface-container-low"
>
{tabs.map((tab) => {
const Icon = tab.icon
const active = tab.match(pathname)
return (
<Link
key={tab.href}
href={tab.href}
aria-label={tab.label}
aria-current={active ? 'page' : undefined}
className={cn(
'flex-1 h-14 flex items-center justify-center transition-colors',
active
? 'bg-primary-container text-primary-container-foreground'
: 'text-muted-foreground hover:text-foreground',
)}
>
<Icon className="size-5" aria-hidden="true" />
</Link>
)
})}
</nav>
)
}