33import type { Member , Task , User } from '@db' ;
44import { ArrowLeft , Folder } from 'lucide-react' ;
55import Image from 'next/image' ;
6- import { usePathname , useRouter } from 'next/navigation' ;
7- import { useMemo , useState } from 'react' ;
6+ import { usePathname , useRouter , useSearchParams } from 'next/navigation' ;
7+ import { useMemo } from 'react' ;
88import { AutomationIndicator } from './AutomationIndicator' ;
99import { TaskStatusSelector } from './TaskStatusSelector' ;
1010
@@ -62,7 +62,7 @@ const statusPalette = {
6262export function TasksByCategory ( { tasks, members, statusFilter } : TasksByCategoryProps ) {
6363 const router = useRouter ( ) ;
6464 const pathname = usePathname ( ) ;
65- const [ selectedCategory , setSelectedCategory ] = useState < string | null > ( null ) ;
65+ const searchParams = useSearchParams ( ) ;
6666
6767 // Group tasks by their first control, or "Uncategorized"
6868 const categories = useMemo ( ( ) => {
@@ -110,6 +110,13 @@ export function TasksByCategory({ tasks, members, statusFilter }: TasksByCategor
110110 return sortedCategories ;
111111 } , [ tasks ] ) ;
112112
113+ // Selected category from URL so it survives back navigation
114+ const categoryFromUrl = searchParams . get ( 'category' ) ;
115+ const selectedCategory = useMemo ( ( ) => {
116+ if ( ! categoryFromUrl ) return null ;
117+ return categories . some ( ( c ) => c . id === categoryFromUrl ) ? categoryFromUrl : null ;
118+ } , [ categoryFromUrl , categories ] ) ;
119+
113120 // Calculate stats for a category
114121 const getCategoryStats = ( categoryTasks : Task [ ] ) => {
115122 const total = categoryTasks . length ;
@@ -129,7 +136,19 @@ export function TasksByCategory({ tasks, members, statusFilter }: TasksByCategor
129136 } ;
130137
131138 const handleCategoryClick = ( categoryId : string ) => {
132- setSelectedCategory ( selectedCategory === categoryId ? null : categoryId ) ;
139+ const next = selectedCategory === categoryId ? null : categoryId ;
140+ const params = new URLSearchParams ( searchParams . toString ( ) ) ;
141+ if ( next ) params . set ( 'category' , next ) ;
142+ else params . delete ( 'category' ) ;
143+ const query = params . toString ( ) ;
144+ router . replace ( query ? `${ pathname } ?${ query } ` : pathname ) ;
145+ } ;
146+
147+ const handleBackToCategories = ( ) => {
148+ const params = new URLSearchParams ( searchParams . toString ( ) ) ;
149+ params . delete ( 'category' ) ;
150+ const query = params . toString ( ) ;
151+ router . replace ( query ? `${ pathname } ?${ query } ` : pathname ) ;
133152 } ;
134153
135154 // If a category is selected, show only that category's tasks
@@ -212,7 +231,7 @@ export function TasksByCategory({ tasks, members, statusFilter }: TasksByCategor
212231 { /* Back button and category header */ }
213232 < div className = "flex items-center justify-between" >
214233 < button
215- onClick = { ( ) => setSelectedCategory ( null ) }
234+ onClick = { handleBackToCategories }
216235 className = "inline-flex items-center gap-2 rounded-sm border border-border/60 px-3 py-1.5 text-[11px] font-medium uppercase tracking-[0.18em] text-muted-foreground transition-colors hover:bg-muted/20 hover:text-foreground"
217236 >
218237 < ArrowLeft className = "h-3 w-3" />
0 commit comments