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:
Mary Kate Fain
2026-02-25 10:10:48 -06:00
parent 4122139bef
commit fa63b60401
3 changed files with 37 additions and 67 deletions
+21 -35
View File
@@ -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 */}
+1 -1
View File
@@ -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 ? (
+15 -31
View File
@@ -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>
);