@@ -27,7 +27,7 @@ import type {
2727} from "@/lib/models/transaction" ;
2828import { MoreVertical , Pencil , Play , Plus , Trash , Upload } from "lucide-react" ;
2929import { usePathname , useRouter , useSearchParams } from "next/navigation" ;
30- import { useCallback , useEffect , useMemo , useState } from "react" ;
30+ import { useCallback , useEffect , useMemo , useRef , useState } from "react" ;
3131import { toast } from "sonner" ;
3232
3333export interface TransactionFiltersState {
@@ -72,6 +72,15 @@ export default function TransactionPage() {
7272 const { data : categories = [ ] } = useCategories ( ) ;
7373 const { data : accounts = [ ] } = useAccounts ( ) ;
7474
75+ const hasSyncedFromUrlRef = useRef ( false ) ;
76+ const pendingUrlSyncRef = useRef ( true ) ;
77+ const parsedStateRef = useRef ( {
78+ page : 1 ,
79+ sortBy : "date" ,
80+ sortOrder : "desc" as "asc" | "desc" ,
81+ filters : initialFilters ,
82+ } ) ;
83+
7584 // Filter state
7685 const [ filters , setFilters ] =
7786 useState < TransactionFiltersState > ( initialFilters ) ;
@@ -144,6 +153,14 @@ export default function TransactionPage() {
144153 search : searchParams . get ( "search" ) || "" ,
145154 } ;
146155
156+ parsedStateRef . current = {
157+ page : nextPage ,
158+ sortBy : nextSortBy ,
159+ sortOrder : nextSortOrder ,
160+ filters : nextFilters ,
161+ } ;
162+ pendingUrlSyncRef . current = true ;
163+
147164 setCurrentPage ( ( prev ) => ( prev === nextPage ? prev : nextPage ) ) ;
148165 setSortBy ( ( prev ) => ( prev === nextSortBy ? prev : nextSortBy ) ) ;
149166 setSortOrder ( ( prev ) => ( prev === nextSortOrder ? prev : nextSortOrder ) ) ;
@@ -152,6 +169,24 @@ export default function TransactionPage() {
152169 ) ;
153170 } , [ searchParams ] ) ;
154171
172+ useEffect ( ( ) => {
173+ if ( ! pendingUrlSyncRef . current ) {
174+ return ;
175+ }
176+
177+ const parsed = parsedStateRef . current ;
178+ const isSynced =
179+ currentPage === parsed . page &&
180+ sortBy === parsed . sortBy &&
181+ sortOrder === parsed . sortOrder &&
182+ areFiltersEqual ( filters , parsed . filters ) ;
183+
184+ if ( isSynced ) {
185+ hasSyncedFromUrlRef . current = true ;
186+ pendingUrlSyncRef . current = false ;
187+ }
188+ } , [ currentPage , sortBy , sortOrder , filters ] ) ;
189+
155190 // Update URL when state changes
156191 const updateUrl = useCallback ( ( ) => {
157192 const params = new URLSearchParams ( ) ;
@@ -172,7 +207,7 @@ export default function TransactionPage() {
172207
173208 const nextQuery = params . toString ( ) ;
174209 const currentQuery = searchParams . toString ( ) ;
175- if ( nextQuery === currentQuery ) {
210+ if ( ! hasSyncedFromUrlRef . current || nextQuery === currentQuery ) {
176211 return ;
177212 }
178213
0 commit comments