11import { useEffect , useState } from 'react' ;
22import { Plus } from 'lucide-react' ;
3- import { useLocation , useNavigate } from 'react-router-dom' ;
4- import { useInitialQueryParams } from '../model/useInitialQueryParams' ;
5- import { updateUrl } from '../lib/updateUrl' ;
3+ import { useSearchParams } from 'react-router-dom' ;
64import { Button , Card } from '@/shared/ui' ;
75import { PostTable } from '@/features/(post)/list-posts' ;
86import { usePosts } from '@/features/(post)/list-posts' ;
@@ -28,33 +26,31 @@ import { useTags } from '../model';
2826import type { Post } from '@/entities/post' ;
2927import type { Comment } from '@/entities/comment' ;
3028import type { User } from '@/entities/user' ;
29+ import { useSearchParamsUtils } from '@/shared/lib/router' ;
3130
3231export function PostsManagerPage ( ) {
33- const navigate = useNavigate ( ) ;
34- const location = useLocation ( ) ;
35- const queryParams = new URLSearchParams ( location . search ) ;
36- const initial = useInitialQueryParams ( ) ;
32+ const [ searchParams ] = useSearchParams ( ) ;
33+ const initialSkip = parseInt ( searchParams . get ( 'skip' ) || '0' ) ;
34+ const initialLimit = parseInt ( searchParams . get ( 'limit' ) || '10' ) ;
35+ const initialSearch = searchParams . get ( 'search' ) || '' ;
36+ const initialSortBy = ( searchParams . get ( 'sortBy' ) as any ) || 'none' ;
37+ const initialSortOrder = ( searchParams . get ( 'sortOrder' ) as any ) || 'asc' ;
38+ const initialTag = searchParams . get ( 'tag' ) || '' ;
3739
3840 // 상태 관리
39- const { limit, skip, next, prev, setPageSize, setSkip } = usePagination (
40- initial . limit ,
41- initial . skip ,
42- ) ;
43- const { searchQuery, setQuery } = usePostSearch ( initial . searchQuery ) ;
41+ const { limit, skip, setPageSize, setSkip } = usePagination ( initialLimit , initialSkip ) ;
42+ const { searchQuery, setQuery } = usePostSearch ( initialSearch ) ;
4443 const [ selectedPost , setSelectedPost ] = useState < Post | null > ( null ) ;
4544 const {
4645 sortBy,
4746 sortOrder,
4847 setBy : setSortBy ,
4948 setOrder : setSortOrder ,
50- } = usePostSort (
51- ( queryParams . get ( 'sortBy' ) as any ) || 'none' ,
52- ( queryParams . get ( 'sortOrder' ) as any ) || 'asc' ,
53- ) ;
49+ } = usePostSort ( initialSortBy , initialSortOrder ) ;
5450 const [ showAddDialog , setShowAddDialog ] = useState ( false ) ;
5551 const [ showEditDialog , setShowEditDialog ] = useState ( false ) ;
5652 const { tags } = useTags ( ) ;
57- const { selectedTag, setTag : setSelectedTag } = useTagFilter ( queryParams . get ( 'tag' ) || '' ) ;
53+ const { selectedTag, setTag : setSelectedTag } = useTagFilter ( initialTag ) ;
5854 const [ selectedComment , setSelectedComment ] = useState < Comment | null > ( null ) ;
5955
6056 const [ showAddCommentDialog , setShowAddCommentDialog ] = useState ( false ) ;
@@ -71,9 +67,7 @@ export function PostsManagerPage() {
7167 sortOrder : ( sortOrder as any ) || 'asc' ,
7268 } ) ;
7369
74- const updateURL = ( ) => {
75- updateUrl ( navigate , { skip, limit, search : searchQuery , sortBy, sortOrder, tag : selectedTag } ) ;
76- } ;
70+ const { update : updateParams } = useSearchParamsUtils ( ) ;
7771
7872 const onPostDeleted = async ( _id : number ) => {
7973 void refetch ( ) ;
@@ -107,33 +101,23 @@ export function PostsManagerPage() {
107101 await userModal . show ( user . id ) ;
108102 } ;
109103
110- useEffect ( ( ) => {
111- updateURL ( ) ;
112- } , [ skip , limit , sortBy , sortOrder , selectedTag , searchQuery ] ) ;
104+ // URL → 상태 동기화만 유지. 상태 → URL은 이벤트 핸들러에서 부분 업데이트로 처리
113105
114106 useEffect ( ( ) => {
115- const params = new URLSearchParams ( location . search ) ;
116- setSkip ( parseInt ( params . get ( 'skip' ) || String ( initial . skip ) ) ) ;
117- setPageSize ( parseInt ( params . get ( 'limit' ) || String ( initial . limit ) ) ) ;
118- setQuery ( params . get ( 'search' ) || initial . searchQuery ) ;
119- setSortBy ( ( params . get ( 'sortBy' ) as any ) || initial . sortBy ) ;
120- setSortOrder ( ( params . get ( 'sortOrder' ) as any ) || initial . sortOrder ) ;
121- setSelectedTag ( params . get ( 'tag' ) || initial . selectedTag ) ;
122- } , [
123- location . search ,
124- setQuery ,
125- setSortBy ,
126- setSortOrder ,
127- setSelectedTag ,
128- initial . skip ,
129- initial . limit ,
130- initial . searchQuery ,
131- initial . sortBy ,
132- initial . sortOrder ,
133- initial . selectedTag ,
134- setPageSize ,
135- setSkip ,
136- ] ) ;
107+ const s = parseInt ( searchParams . get ( 'skip' ) || String ( initialSkip ) ) ;
108+ const l = parseInt ( searchParams . get ( 'limit' ) || String ( initialLimit ) ) ;
109+ const q = searchParams . get ( 'search' ) || initialSearch ;
110+ const sb = ( searchParams . get ( 'sortBy' ) as any ) || initialSortBy ;
111+ const so = ( searchParams . get ( 'sortOrder' ) as any ) || initialSortOrder ;
112+ const t = searchParams . get ( 'tag' ) || initialTag ;
113+
114+ if ( s !== skip ) setSkip ( s ) ;
115+ if ( l !== limit ) setPageSize ( l ) ;
116+ if ( q !== searchQuery ) setQuery ( q ) ;
117+ if ( sb !== sortBy ) setSortBy ( sb as any ) ;
118+ if ( so !== sortOrder ) setSortOrder ( so as any ) ;
119+ if ( t !== selectedTag ) setSelectedTag ( t ) ;
120+ } , [ searchParams ] ) ;
137121
138122 const renderPostTable = ( ) => (
139123 < PostTable
@@ -143,7 +127,7 @@ export function PostsManagerPage() {
143127 selectedTag = { selectedTag }
144128 onClickTag = { ( tag ) => {
145129 setSelectedTag ( tag ) ;
146- updateURL ( ) ;
130+ updateParams ( { tag } , { push : true } ) ;
147131 } }
148132 onOpenDetail = { ( post ) => openPostDetail ( post ) }
149133 onOpenUser = { ( userId ) => openUserModal ( { id : userId } as User ) }
@@ -203,14 +187,20 @@ export function PostsManagerPage() {
203187 tags = { tags }
204188 onChange = { ( value ) => {
205189 setSelectedTag ( value ) ;
206- updateURL ( ) ;
190+ updateParams ( { tag : value , skip : 0 } , { push : true } ) ;
207191 } }
208192 />
209193 < SortSelect
210194 sortBy = { sortBy as any }
211195 sortOrder = { sortOrder as any }
212- onChangeBy = { ( v ) => setSortBy ( v as any ) }
213- onChangeOrder = { ( v ) => setSortOrder ( v as any ) }
196+ onChangeBy = { ( v ) => {
197+ setSortBy ( v as any ) ;
198+ updateParams ( { sortBy : v as any , skip : 0 } , { push : true } ) ;
199+ } }
200+ onChangeOrder = { ( v ) => {
201+ setSortOrder ( v as any ) ;
202+ updateParams ( { sortOrder : v as any , skip : 0 } , { push : true } ) ;
203+ } }
214204 />
215205 </ div >
216206
@@ -220,9 +210,9 @@ export function PostsManagerPage() {
220210 limit = { limit }
221211 skip = { skip }
222212 total = { total }
223- onPrev = { prev }
224- onNext = { next }
225- onChangeLimit = { ( v ) => setPageSize ( v ) }
213+ onPrev = { ( ) => updateParams ( { skip : Math . max ( 0 , skip - limit ) } , { push : true } ) }
214+ onNext = { ( ) => updateParams ( { skip : Math . min ( total , skip + limit ) } , { push : true } ) }
215+ onChangeLimit = { ( v ) => updateParams ( { limit : v , skip : 0 } , { push : true } ) }
226216 />
227217 </ div >
228218 </ Card . Content >
0 commit comments