From 831e3c268abc3f671f180a8aa81ba5c638feafdb Mon Sep 17 00:00:00 2001 From: Abhishek Chatterjee Date: Wed, 26 Aug 2026 20:52:03 +0530 Subject: [PATCH] feat(frontend): #55: show grabbing cursor while dragging app window --- frontend/src/components/items/AuthLayout.tsx | 13 +++++++-- frontend/src/components/items/Header.tsx | 7 ++++- frontend/src/hooks/useWindowDrag.ts | 28 ++++++++++++++++++++ 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 frontend/src/hooks/useWindowDrag.ts diff --git a/frontend/src/components/items/AuthLayout.tsx b/frontend/src/components/items/AuthLayout.tsx index f7576a3..938fb78 100644 --- a/frontend/src/components/items/AuthLayout.tsx +++ b/frontend/src/components/items/AuthLayout.tsx @@ -3,6 +3,7 @@ import type { ReactNode } from 'react'; import { useTranslation } from 'react-i18next'; import logo from '@/assets/images/logo.png'; +import { useWindowDrag } from '@/hooks/useWindowDrag'; type AuthLayoutProps = { children: ReactNode; @@ -28,11 +29,16 @@ const features = [ export default function AuthLayout({ children }: AuthLayoutProps) { const { t } = useTranslation(); + const asideDrag = useWindowDrag(); + const mainDrag = useWindowDrag(); return (
-
diff --git a/frontend/src/components/items/Header.tsx b/frontend/src/components/items/Header.tsx index ee8cf71..2c4c198 100644 --- a/frontend/src/components/items/Header.tsx +++ b/frontend/src/components/items/Header.tsx @@ -5,6 +5,7 @@ import { useNavigate } from 'react-router-dom'; import { useAuth } from '@/context/AuthContext'; import { useSearch } from '@/context/SearchContext'; +import { useWindowDrag } from '@/hooks/useWindowDrag'; export default function Header() { const { t } = useTranslation(); @@ -12,6 +13,7 @@ export default function Header() { const { query, setQuery, clear } = useSearch(); const navigate = useNavigate(); const [menuOpen, setMenuOpen] = useState(false); + const { cursorClass, dragHandlers } = useWindowDrag(); const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); @@ -31,7 +33,10 @@ export default function Header() { }; return ( -
+
{/* Central Search Drive Input (Only visible when logged in) */} {session ? ( diff --git a/frontend/src/hooks/useWindowDrag.ts b/frontend/src/hooks/useWindowDrag.ts new file mode 100644 index 0000000..553d0d5 --- /dev/null +++ b/frontend/src/hooks/useWindowDrag.ts @@ -0,0 +1,28 @@ +import { useCallback, useEffect, useState } from 'react'; + +export function useWindowDrag() { + const [dragging, setDragging] = useState(false); + + const stopDragging = useCallback(() => setDragging(false), []); + + useEffect(() => { + window.addEventListener('mouseup', stopDragging); + window.addEventListener('blur', stopDragging); + return () => { + window.removeEventListener('mouseup', stopDragging); + window.removeEventListener('blur', stopDragging); + }; + }, [stopDragging]); + + const dragHandlers = { + onMouseDown: useCallback(() => setDragging(true), []), + onMouseUp: stopDragging, + onMouseLeave: stopDragging, + }; + + return { + dragging, + cursorClass: dragging ? 'cursor-grabbing' : '', + dragHandlers, + }; +}