Rework mobile nav: logo-home top-left, hamburger top-right, new bottom tabs
- Top bar: logo on left (navigates to / with scroll-to-top), hamburger menu on right (replaces search icon). Cleaner two-element layout. - Bottom nav: remove Home tab (logo serves this purpose). New tab order when logged in: You | Notifications | Explore | Search. When logged out: Explore | Search. - Drawer slides from right (matching hamburger position) instead of left. - Search is now always visible in bottom nav for both logged-in and logged-out users.
This commit is contained in:
@@ -169,12 +169,6 @@ export function MobileBottomNav() {
|
||||
useSensor(PointerSensor, { activationConstraint: { distance: 5 } }),
|
||||
);
|
||||
|
||||
const handleHomeClick = useCallback(() => {
|
||||
if (location.pathname === '/') {
|
||||
window.scrollTo({ top: 0, behavior: 'smooth' });
|
||||
}
|
||||
}, [location.pathname]);
|
||||
|
||||
const handleDragEnd = useCallback((event: DragEndEvent) => {
|
||||
const { active, over } = event;
|
||||
if (!over || active.id === over.id) return;
|
||||
@@ -197,9 +191,9 @@ export function MobileBottomNav() {
|
||||
}));
|
||||
}, [orderedItems]);
|
||||
|
||||
// Check if current path matches any explore route (excluding __feed which is the Home tab)
|
||||
// Check if current path matches any explore route
|
||||
const isExploreActive = orderedItems.some((id) =>
|
||||
id !== '__feed' && isItemActive(id, location.pathname, location.search),
|
||||
isItemActive(id, location.pathname, location.search),
|
||||
);
|
||||
|
||||
const handleDrawerClose = (open: boolean) => {
|
||||
@@ -210,21 +204,14 @@ export function MobileBottomNav() {
|
||||
return (
|
||||
<>
|
||||
<nav className="fixed bottom-0 left-0 right-0 z-20 flex items-center bg-background/80 backdrop-blur-md border-t border-border sidebar:hidden safe-area-bottom">
|
||||
<NavTab
|
||||
to="/"
|
||||
icon={<Home className="size-5" />}
|
||||
label="Home"
|
||||
active={location.pathname === '/'}
|
||||
onClick={handleHomeClick}
|
||||
/>
|
||||
<NavTab
|
||||
icon={<Compass className="size-5" />}
|
||||
label="Explore"
|
||||
active={isExploreActive}
|
||||
onClick={() => setExploreOpen(true)}
|
||||
/>
|
||||
{user ? (
|
||||
{user && (
|
||||
<>
|
||||
<NavTab
|
||||
to={userProfileUrl}
|
||||
icon={<User className="size-5" />}
|
||||
label="You"
|
||||
active={location.pathname === userProfileUrl}
|
||||
/>
|
||||
<NavTab
|
||||
to="/notifications"
|
||||
icon={<Bell className="size-5" />}
|
||||
@@ -232,21 +219,20 @@ export function MobileBottomNav() {
|
||||
active={location.pathname === '/notifications'}
|
||||
showIndicator={hasUnread}
|
||||
/>
|
||||
<NavTab
|
||||
to={userProfileUrl}
|
||||
icon={<User className="size-5" />}
|
||||
label="You"
|
||||
active={location.pathname === userProfileUrl}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<NavTab
|
||||
to="/search"
|
||||
icon={<Search className="size-5" />}
|
||||
label="Search"
|
||||
active={location.pathname === '/search'}
|
||||
/>
|
||||
)}
|
||||
<NavTab
|
||||
icon={<Compass className="size-5" />}
|
||||
label="Explore"
|
||||
active={isExploreActive}
|
||||
onClick={() => setExploreOpen(true)}
|
||||
/>
|
||||
<NavTab
|
||||
to="/search"
|
||||
icon={<Search className="size-5" />}
|
||||
label="Search"
|
||||
active={location.pathname === '/search'}
|
||||
/>
|
||||
</nav>
|
||||
|
||||
{/* Explore bottom sheet */}
|
||||
|
||||
@@ -114,7 +114,7 @@ export function MobileDrawer({ open, onOpenChange }: MobileDrawerProps) {
|
||||
|
||||
return (
|
||||
<Sheet open={open} onOpenChange={onOpenChange}>
|
||||
<SheetContent side="left" className="w-[300px] p-0 border-r-border">
|
||||
<SheetContent side="right" className="w-[300px] p-0 border-l-border">
|
||||
<SheetTitle className="sr-only">Navigation menu</SheetTitle>
|
||||
|
||||
{user ? (
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useCallback } from 'react';
|
||||
import { Link, useLocation, useNavigate } from 'react-router-dom';
|
||||
import { Menu, Search } from 'lucide-react';
|
||||
import { Link, useLocation } from 'react-router-dom';
|
||||
import { Menu } from 'lucide-react';
|
||||
import { DittoLogo } from '@/components/DittoLogo';
|
||||
|
||||
interface MobileTopBarProps {
|
||||
@@ -9,7 +9,6 @@ interface MobileTopBarProps {
|
||||
|
||||
export function MobileTopBar({ onMenuClick }: MobileTopBarProps) {
|
||||
const location = useLocation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleLogoClick = useCallback((e: React.MouseEvent) => {
|
||||
if (location.pathname === '/') {
|
||||
@@ -20,35 +19,20 @@ export function MobileTopBar({ onMenuClick }: MobileTopBarProps) {
|
||||
|
||||
return (
|
||||
<header className="sticky top-0 z-20 bg-background/80 backdrop-blur-md border-b border-border sidebar:hidden safe-area-top">
|
||||
<div className="flex items-center px-3 h-12">
|
||||
{/* Left: hamburger menu */}
|
||||
<div className="flex items-center justify-center w-7 shrink-0">
|
||||
<button
|
||||
onClick={onMenuClick}
|
||||
className="rounded-lg p-0.5 text-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-1 focus:ring-offset-background transition-colors hover:bg-secondary/60"
|
||||
aria-label="Open menu"
|
||||
>
|
||||
<Menu className="size-6" />
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex items-center justify-between px-3 h-12">
|
||||
{/* Left: Logo / Home */}
|
||||
<Link to="/" onClick={handleLogoClick} className="shrink-0">
|
||||
<DittoLogo size={28} />
|
||||
</Link>
|
||||
|
||||
{/* Center: Ditto logo */}
|
||||
<div className="flex-1 flex items-center justify-center">
|
||||
<Link to="/" onClick={handleLogoClick}>
|
||||
<DittoLogo size={28} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
{/* Right: search icon */}
|
||||
<div className="flex items-center justify-center w-7 shrink-0">
|
||||
<button
|
||||
onClick={() => navigate('/search')}
|
||||
className="rounded-lg p-0.5 text-muted-foreground hover:text-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-1 focus:ring-offset-background transition-colors hover:bg-secondary/60"
|
||||
aria-label="Search"
|
||||
>
|
||||
<Search className="size-5" />
|
||||
</button>
|
||||
</div>
|
||||
{/* Right: hamburger menu */}
|
||||
<button
|
||||
onClick={onMenuClick}
|
||||
className="shrink-0 rounded-lg p-0.5 text-foreground focus:outline-none focus:ring-2 focus:ring-primary focus:ring-offset-1 focus:ring-offset-background transition-colors hover:bg-secondary/60"
|
||||
aria-label="Open menu"
|
||||
>
|
||||
<Menu className="size-6" />
|
||||
</button>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user