Files
edr-platform/apps/edr-passenger-web/portal/src/components/BottomTabBar.tsx

70 lines
2.7 KiB
TypeScript

'use client';
import { Home, Phone, Ticket, User } from 'lucide-react';
import Link from 'next/link';
import { usePathname } from 'next/navigation';
import { useAuthStore } from '@/lib/auth-store';
// The linear, one-screen-at-a-time booking flow — each of these pages already
// has its own sticky mobile CTA bar (and the mobile step strip at the top),
// so the tab bar hides rather than stacking a second bottom bar underneath.
const LINEAR_FLOW_PREFIXES = [
'/booking/search',
'/booking/results',
'/booking/seats',
'/booking/passengers',
'/booking/auth-check',
'/booking/review',
'/booking/payment',
'/booking/confirmation',
];
export default function BottomTabBar() {
const pathname = usePathname() ?? '';
const isAuthenticated = useAuthStore((s) => s.isAuthenticated);
const isInLinearFlow = LINEAR_FLOW_PREFIXES.some((p) => pathname.startsWith(p));
if (isInLinearFlow) return null;
const tabs = [
{ href: '/', label: 'Home', icon: Home, match: (p: string) => p === '/' },
{ href: '/booking/lookup', label: 'Bookings', icon: Ticket, match: (p: string) => p.startsWith('/booking/lookup') || p.startsWith('/booking/detail') },
{ href: '/contact', label: 'Contact', icon: Phone, match: (p: string) => p.startsWith('/contact') },
{
href: isAuthenticated ? '/profile' : '/login',
label: isAuthenticated ? 'Account' : 'Sign in',
icon: User,
match: (p: string) => p.startsWith('/profile') || p.startsWith('/login') || p.startsWith('/register'),
},
];
return (
<>
{/* In-flow spacer so page content/Footer can't end up hidden behind the
fixed bar below — self-contained here so it only exists when the
bar itself is actually rendered. */}
<div className="lg:hidden h-16" aria-hidden="true" />
<nav className="lg:hidden fixed bottom-0 inset-x-0 z-40 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-800 shadow-[0_-2px_10px_rgba(0,0,0,0.05)]">
<ul className="flex items-stretch">
{tabs.map(({ href, label, icon: Icon, match }) => {
const isActive = match(pathname);
return (
<li key={href} className="flex-1">
<Link
href={href}
className={`flex flex-col items-center justify-center gap-0.5 py-2.5 text-[11px] font-medium transition-colors ${
isActive ? 'text-primary' : 'text-gray-500 dark:text-gray-400'
}`}
>
<Icon className={`w-5 h-5 ${isActive ? 'text-primary' : ''}`} strokeWidth={isActive ? 2.5 : 2} />
{label}
</Link>
</li>
);
})}
</ul>
</nav>
</>
);
}