From d76446dc6e680666a8b90468161db7e3daa732dd Mon Sep 17 00:00:00 2001 From: greedy-wudpeckr Date: Thu, 5 Feb 2026 15:05:15 +0530 Subject: [PATCH 1/2] fix : mobile-navbar Signed-off-by: greedy-wudpeckr --- .../HomeComponents/Navbar/NavbarMobile.tsx | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/frontend/src/components/HomeComponents/Navbar/NavbarMobile.tsx b/frontend/src/components/HomeComponents/Navbar/NavbarMobile.tsx index 491a3b40..ca34c0dd 100644 --- a/frontend/src/components/HomeComponents/Navbar/NavbarMobile.tsx +++ b/frontend/src/components/HomeComponents/Navbar/NavbarMobile.tsx @@ -106,6 +106,23 @@ export const NavbarMobile = ( props.setIsOpen(false); }; + const handleNavClick = ( + e: React.MouseEvent, + href: string + ) => { + e.preventDefault(); + props.setIsOpen(false); + + // Wait for sheet to close, then scroll + setTimeout(() => { + const targetId = href.replace('#', ''); + const element = document.getElementById(targetId); + if (element) { + element.scrollIntoView({ behavior: 'smooth', block: 'start' }); + } + }, 300); + }; + return ( @@ -132,7 +149,7 @@ export const NavbarMobile = ( rel="noreferrer noopener" key={label} href={href} - onClick={() => props.setIsOpen(false)} + onClick={(e) => handleNavClick(e, href)} className={buttonVariants({ variant: 'ghost' })} > {label} From 44d489419aa98483bbc10de29ab235785f9c8604 Mon Sep 17 00:00:00 2001 From: greedy-wudpeckr Date: Thu, 5 Feb 2026 15:06:06 +0530 Subject: [PATCH 2/2] added tests for navbar-mobile Signed-off-by: greedy-wudpeckr --- .../Navbar/__tests__/NavbarMobile.test.tsx | 111 ++++++++++++++++++ 1 file changed, 111 insertions(+) diff --git a/frontend/src/components/HomeComponents/Navbar/__tests__/NavbarMobile.test.tsx b/frontend/src/components/HomeComponents/Navbar/__tests__/NavbarMobile.test.tsx index eb810e35..68ee07eb 100644 --- a/frontend/src/components/HomeComponents/Navbar/__tests__/NavbarMobile.test.tsx +++ b/frontend/src/components/HomeComponents/Navbar/__tests__/NavbarMobile.test.tsx @@ -151,6 +151,117 @@ describe('NavbarMobile', () => { expect(screen.getByText(/Enable Auto-Sync/i)).toBeInTheDocument(); }); + + describe('Navigation link click behavior', () => { + beforeEach(() => { + // Mock scrollIntoView + Element.prototype.scrollIntoView = jest.fn(); + // Mock setTimeout + jest.useFakeTimers(); + }); + + afterEach(() => { + jest.runOnlyPendingTimers(); + jest.useRealTimers(); + }); + + it('should close the sheet immediately when clicking a nav link', () => { + render(); + + const tasksLink = screen.getByText('Tasks'); + fireEvent.click(tasksLink); + + expect(mockSetIsOpen).toHaveBeenCalledWith(false); + }); + + it('should scroll to target element after 300ms delay', () => { + // Create a mock element + const mockElement = document.createElement('div'); + mockElement.id = 'tasks'; + document.body.appendChild(mockElement); + mockElement.scrollIntoView = jest.fn(); + + render(); + + const tasksLink = screen.getByText('Tasks'); + fireEvent.click(tasksLink); + + // scrollIntoView should not be called immediately + expect(mockElement.scrollIntoView).not.toHaveBeenCalled(); + + // Fast-forward time by 300ms + jest.advanceTimersByTime(300); + + // Now scrollIntoView should have been called + expect(mockElement.scrollIntoView).toHaveBeenCalledWith({ + behavior: 'smooth', + block: 'start', + }); + + // Cleanup + document.body.removeChild(mockElement); + }); + + it('should extract the correct target ID from href', () => { + const mockElement = document.createElement('div'); + mockElement.id = 'setup-guide'; + document.body.appendChild(mockElement); + mockElement.scrollIntoView = jest.fn(); + + render(); + + const setupGuideLink = screen.getByText('Setup Guide'); + fireEvent.click(setupGuideLink); + + jest.advanceTimersByTime(300); + + expect(mockElement.scrollIntoView).toHaveBeenCalledWith({ + behavior: 'smooth', + block: 'start', + }); + + document.body.removeChild(mockElement); + }); + + it('should handle case when target element does not exist', () => { + render(); + + const homeLink = screen.getByText('Home'); + fireEvent.click(homeLink); + + // Should not throw an error even if element doesn't exist + expect(() => { + jest.advanceTimersByTime(300); + }).not.toThrow(); + }); + + it('should handle multiple rapid clicks correctly', () => { + const mockElement = document.createElement('div'); + mockElement.id = 'tasks'; + document.body.appendChild(mockElement); + mockElement.scrollIntoView = jest.fn(); + + render(); + + const tasksLink = screen.getByText('Tasks'); + + // Click multiple times + fireEvent.click(tasksLink); + fireEvent.click(tasksLink); + fireEvent.click(tasksLink); + + // Sheet should be closed on each click + expect(mockSetIsOpen).toHaveBeenCalledTimes(3); + expect(mockSetIsOpen).toHaveBeenCalledWith(false); + + jest.advanceTimersByTime(300); + + // scrollIntoView should be called for each click + expect(mockElement.scrollIntoView).toHaveBeenCalledTimes(3); + + document.body.removeChild(mockElement); + }); + }); }); describe('NavbarMobile component using snapshot', () => {