From 93cb7d2afbf442974ff7cb9d568c95bf37232e4b Mon Sep 17 00:00:00 2001 From: devjayy43 Date: Mon, 31 Aug 2026 09:27:23 +0100 Subject: [PATCH] feat: add improvements to mobile-nav and toast components - Mobile Nav (#266): Add user info section with wallet address, swipe-to-top gesture, improved touch targets (44px), and smooth animations - Toast Provider (#268): Add progress bar for auto-dismiss countdown, improving UX feedback for timed notifications --- src/components/layout/mobile-nav.tsx | 60 +++++++++++++++++++++++++--- src/components/shared/toast.tsx | 58 ++++++++++++++++++--------- 2 files changed, 95 insertions(+), 23 deletions(-) diff --git a/src/components/layout/mobile-nav.tsx b/src/components/layout/mobile-nav.tsx index 73b1bf1..7c4d9f7 100644 --- a/src/components/layout/mobile-nav.tsx +++ b/src/components/layout/mobile-nav.tsx @@ -5,16 +5,66 @@ import { usePathname } from "next/navigation"; import { useAuthStore } from "@/store/auth-store"; import { cn } from "@/lib/utils/cn"; import { isNavLinkActive, navLinks } from "./nav-links"; +import { useState, useRef, useEffect } from "react"; +import { Avatar, AvatarFallback, getInitials } from "@/components/ui/avatar"; +import { truncateAddress } from "@/lib/utils/format"; export function MobileNav() { const pathname = usePathname(); const isAuthenticated = useAuthStore((s) => s.isAuthenticated); const hasHydrated = useAuthStore((s) => s.hasHydrated); + const walletAddress = useAuthStore((s) => s.walletAddress); + const [swipeStartX, setSwipeStartX] = useState(0); + const touchRef = useRef(null); + + useEffect(() => { + const handleTouchStart = (e: TouchEvent) => { + setSwipeStartX(e.touches[0].clientX); + }; + + const handleTouchEnd = (e: TouchEvent) => { + const swipeEndX = e.changedTouches[0].clientX; + const diff = swipeEndX - swipeStartX; + if (Math.abs(diff) > 50 && diff > 0) { + window.scrollTo({ top: 0, behavior: "smooth" }); + } + }; + + const nav = touchRef.current; + if (nav) { + nav.addEventListener("touchstart", handleTouchStart); + nav.addEventListener("touchend", handleTouchEnd); + return () => { + nav.removeEventListener("touchstart", handleTouchStart); + nav.removeEventListener("touchend", handleTouchEnd); + }; + } + }, [swipeStartX]); if (!hasHydrated || !isAuthenticated) return null; return ( -