@@ -11,7 +11,7 @@ import {
1111} from "lucide-react" ;
1212import Link from "next/link" ;
1313import { useRouter } from "next/router" ;
14- import { useEffect , useMemo , useRef , useState } from "react" ;
14+ import { useEffect , useMemo , useState } from "react" ;
1515import { toast } from "sonner" ;
1616import { BreadcrumbSidebar } from "@/components/shared/breadcrumb-sidebar" ;
1717import { DateTooltip } from "@/components/shared/date-tooltip" ;
@@ -66,16 +66,12 @@ export const ShowProjects = () => {
6666 const { data, isLoading } = api . project . all . useQuery ( ) ;
6767 const { data : auth } = api . user . get . useQuery ( ) ;
6868 const { mutateAsync } = api . project . remove . useMutation ( ) ;
69- const [ searchQuery , setSearchQuery ] = useState ( ( ) => {
70- // Initialize from URL query parameter on mount
71- if ( typeof window !== "undefined" ) {
72- const urlQuery = router . query . q ;
73- return typeof urlQuery === "string" ? urlQuery : "" ;
74- }
75- return "" ;
76- } ) ;
69+
70+ const [ searchQuery , setSearchQuery ] = useState (
71+ router . isReady && typeof router . query . q === "string" ? router . query . q : "" ,
72+ ) ;
7773 const debouncedSearchQuery = useDebounce ( searchQuery , 500 ) ;
78- const isUrlSync = useRef ( false ) ;
74+
7975 const [ sortBy , setSortBy ] = useState < string > ( ( ) => {
8076 if ( typeof window !== "undefined" ) {
8177 return localStorage . getItem ( "projectsSort" ) || "createdAt-desc" ;
@@ -87,63 +83,33 @@ export const ShowProjects = () => {
8783 localStorage . setItem ( "projectsSort" , sortBy ) ;
8884 } , [ sortBy ] ) ;
8985
90- // Sync URL changes back to state (e.g., browser back/forward)
91- // NOTE: This effect MUST appear before the URL sync effect below
92- // because React executes effects in order. When the back button is pressed,
93- // we need to set isUrlSync.current = true BEFORE the URL sync effect runs.
9486 useEffect ( ( ) => {
9587 if ( ! router . isReady ) return ;
96-
97- const urlQuery = router . query . q ;
98- const urlSearchQuery = typeof urlQuery === "string" ? urlQuery : "" ;
99-
100- // Update local state if URL changed externally (e.g., browser navigation)
101- if ( urlSearchQuery !== searchQuery ) {
102- isUrlSync . current = true ;
103- setSearchQuery ( urlSearchQuery ) ;
88+ const urlQuery = typeof router . query . q === "string" ? router . query . q : "" ;
89+ if ( urlQuery !== searchQuery ) {
90+ setSearchQuery ( urlQuery ) ;
10491 }
105- // eslint-disable-next-line react-hooks/exhaustive-deps
10692 } , [ router . isReady , router . query . q ] ) ;
10793
108- // Sync search query to URL when debounced value changes
10994 useEffect ( ( ) => {
11095 if ( ! router . isReady ) return ;
96+ const urlQuery = typeof router . query . q === "string" ? router . query . q : "" ;
97+ if ( debouncedSearchQuery === urlQuery ) return ;
11198
112- // Skip if this change came from URL navigation (browser back/forward)
113- if ( isUrlSync . current ) {
114- isUrlSync . current = false ;
115- return ;
99+ const newQuery = { ...router . query } ;
100+ if ( debouncedSearchQuery ) {
101+ newQuery . q = debouncedSearchQuery ;
102+ } else {
103+ delete newQuery . q ;
116104 }
117-
118- const currentQuery = router . query . q ;
119- const normalizedCurrentQuery =
120- typeof currentQuery === "string" ? currentQuery : "" ;
121-
122- // Only update URL if the debounced value is different from current URL
123- if ( debouncedSearchQuery !== normalizedCurrentQuery ) {
124- const newQuery = { ...router . query } ;
125-
126- if ( debouncedSearchQuery ) {
127- newQuery . q = debouncedSearchQuery ;
128- } else {
129- delete newQuery . q ;
130- }
131-
132- router . push (
133- {
134- pathname : router . pathname ,
135- query : newQuery ,
136- } ,
137- undefined ,
138- { shallow : false } ,
139- ) ;
140- }
141- } , [ debouncedSearchQuery , router ] ) ;
105+ router . replace ( { pathname : router . pathname , query : newQuery } , undefined , {
106+ shallow : true ,
107+ } ) ;
108+ } , [ debouncedSearchQuery ] ) ;
142109
143110 const filteredProjects = useMemo ( ( ) => {
144111 if ( ! data ) return [ ] ;
145112
146- // First filter by search query
147113 const filtered = data . filter (
148114 ( project ) =>
149115 project . name
0 commit comments