From 093944e8c476e71266386234f435f4dc44c7e7de Mon Sep 17 00:00:00 2001 From: Chneemann Date: Wed, 26 Aug 2026 09:11:26 +0200 Subject: [PATCH] feat(search): hide searchbar instantly via window.history state when task modal is open --- app/(app)/dashboard/modal/TaskModal.tsx | 51 +++++++++++++++++++++---- app/components/ui/SearchBar.tsx | 6 ++- 2 files changed, 49 insertions(+), 8 deletions(-) diff --git a/app/(app)/dashboard/modal/TaskModal.tsx b/app/(app)/dashboard/modal/TaskModal.tsx index e725fa0..89413ac 100644 --- a/app/(app)/dashboard/modal/TaskModal.tsx +++ b/app/(app)/dashboard/modal/TaskModal.tsx @@ -36,7 +36,7 @@ interface TaskModalProps { /** * Renders a full task detail modal with status indicators, priority details, description, assignees, and creator-only action buttons. - * Integrates keydown listeners to dismiss the modal on pressing the Escape key. + * Supports ESC key navigation and updates URL query parameters dynamically. * * @param {TaskModalProps} props - The component props. * @returns {JSX.Element | null} The rendered modal component or null when no task is selected. @@ -46,13 +46,13 @@ export default function TaskModal({ task, onClose, onDelete }: TaskModalProps) { useEffect(() => { /** - * Keyboard event handler closing the modal dialog when pressing the Escape key. + * Attaches a global keydown event listener to close the modal when the Escape key is pressed. * - * @param {KeyboardEvent} e - The global window keydown event. + * @param {KeyboardEvent} e - The keyboard event object. */ const handleKeyDown = (e: KeyboardEvent) => { if (e.key === "Escape") { - onClose(); + handleClose(); } }; window.addEventListener("keydown", handleKeyDown); @@ -61,6 +61,43 @@ export default function TaskModal({ task, onClose, onDelete }: TaskModalProps) { }; }, [onClose]); + useEffect(() => { + /** + * Updates the URL search parameters to include `modal=task-detail` when a task is selected, + * maintaining modal state in the browser history without triggering a full page re-render. + */ + if (task) { + const params = new URLSearchParams(window.location.search); + if (params.get("modal") !== "task-detail") { + params.set("modal", "task-detail"); + window.history.replaceState( + {}, + "", + `${window.location.pathname}?${params.toString()}`, + ); + } + } + }, [task]); + + /** + * Removes modal query parameters from the browser location history without causing a Next.js soft navigation, then triggers onClose. + */ + const handleClose = () => { + const params = new URLSearchParams(window.location.search); + params.delete("modal"); + const newQuery = params.toString(); + + window.history.replaceState( + {}, + "", + newQuery + ? `${window.location.pathname}?${newQuery}` + : window.location.pathname, + ); + + onClose(); + }; + if (!task) return null; const priorityConfig = task.priority && PRIORITY_CONFIG[task.priority]; @@ -72,7 +109,7 @@ export default function TaskModal({ task, onClose, onDelete }: TaskModalProps) { return (