1
1
import { isAxiosError } from 'axios' ;
2
2
import { motion } from 'motion/react' ;
3
- import { useMemo , useRef , useState } from 'react' ;
3
+ import { useEffect , useMemo , useRef , useState } from 'react' ;
4
4
import { GrValidate } from 'react-icons/gr' ;
5
5
import { IoClose , IoShareSocialOutline } from 'react-icons/io5' ;
6
6
import { useShallow } from 'zustand/react/shallow' ;
@@ -13,8 +13,9 @@ import { SessionParticipantsModal } from '@/features/get-session-users';
13
13
import { useSocket } from '@/features/socket' ;
14
14
import { postSessionTerminate , SessionTerminateModal } from '@/features/terminate-session' ;
15
15
16
- import { useSessionStore } from '@/entities/session' ;
16
+ import { Question , useSessionStore } from '@/entities/session' ;
17
17
18
+ import { deepEqual } from '@/shared/model/deep-equal' ;
18
19
import { Button } from '@/shared/ui/button' ;
19
20
import { useModal } from '@/shared/ui/modal' ;
20
21
import { useToastStore } from '@/shared/ui/toast' ;
@@ -78,37 +79,6 @@ function QuestionList() {
78
79
79
80
const buttonRef = useRef < HTMLButtonElement > ( null ) ;
80
81
81
- const sections = useMemo (
82
- ( ) => [
83
- {
84
- title : '고정된 질문' ,
85
- initialOpen : true ,
86
- questions : questions
87
- . filter ( ( question ) => question . pinned && ! question . closed )
88
- . sort ( ( a , b ) => b . likesCount - a . likesCount ) ,
89
- } ,
90
- {
91
- title : '질문' ,
92
- initialOpen : true ,
93
- questions : questions
94
- . filter ( ( question ) => ! question . pinned && ! question . closed )
95
- . sort ( ( a , b ) => b . likesCount - a . likesCount ) ,
96
- } ,
97
- {
98
- title : '답변 완료된 질문' ,
99
- initialOpen : false ,
100
- questions : questions
101
- . filter ( ( question ) => question . closed )
102
- . sort ( ( a , b ) => {
103
- if ( a . pinned && ! b . pinned ) return - 1 ;
104
- if ( ! a . pinned && b . pinned ) return 1 ;
105
- return b . likesCount - a . likesCount ;
106
- } ) ,
107
- } ,
108
- ] ,
109
- [ questions ] ,
110
- ) ;
111
-
112
82
const sessionButtons = useMemo (
113
83
( ) => [
114
84
{
@@ -164,6 +134,40 @@ function QuestionList() {
164
134
[ sessionId , addToast , openSessionParticipantsModal , openSessionTerminateModal ] ,
165
135
) ;
166
136
137
+ const [ pinnedQuestions , setPinnedQuestions ] = useState < Question [ ] > ( [ ] ) ;
138
+ const [ unpinnedQuestions , setUnpinnedQuestions ] = useState < Question [ ] > ( [ ] ) ;
139
+ const [ closedQuestions , setClosedQuestions ] = useState < Question [ ] > ( [ ] ) ;
140
+
141
+ useEffect ( ( ) => {
142
+ const updatedPinnedQuestions = questions
143
+ . filter ( ( question ) => question . pinned && ! question . closed )
144
+ . sort ( ( a , b ) => b . likesCount - a . likesCount ) ;
145
+
146
+ const updatedUnpinnedQuestions = questions
147
+ . filter ( ( question ) => ! question . pinned && ! question . closed )
148
+ . sort ( ( a , b ) => b . likesCount - a . likesCount ) ;
149
+
150
+ const updatedClosedQuestions = questions
151
+ . filter ( ( question ) => question . closed )
152
+ . sort ( ( a , b ) => {
153
+ if ( a . pinned && ! b . pinned ) return - 1 ;
154
+ if ( ! a . pinned && b . pinned ) return 1 ;
155
+ return b . likesCount - a . likesCount ;
156
+ } ) ;
157
+
158
+ if ( ! deepEqual ( updatedPinnedQuestions , pinnedQuestions ) ) {
159
+ setPinnedQuestions ( updatedPinnedQuestions ) ;
160
+ }
161
+
162
+ if ( ! deepEqual ( updatedUnpinnedQuestions , unpinnedQuestions ) ) {
163
+ setUnpinnedQuestions ( updatedUnpinnedQuestions ) ;
164
+ }
165
+
166
+ if ( ! deepEqual ( updatedClosedQuestions , closedQuestions ) ) {
167
+ setClosedQuestions ( updatedClosedQuestions ) ;
168
+ }
169
+ } , [ questions , pinnedQuestions , unpinnedQuestions , closedQuestions ] ) ;
170
+
167
171
return (
168
172
< div className = 'inline-flex h-full w-4/5 flex-grow flex-col items-center justify-start rounded-lg bg-white shadow' >
169
173
< div className = 'inline-flex h-[54px] w-full items-center justify-between border-b border-gray-200 px-8 py-2' >
@@ -210,15 +214,24 @@ function QuestionList() {
210
214
</ div >
211
215
) : (
212
216
< motion . div className = 'inline-flex h-full w-full flex-col items-start justify-start gap-4 overflow-y-auto px-8 py-4' >
213
- { sections . map ( ( section ) => (
214
- < QuestionSection
215
- key = { section . title }
216
- title = { section . title }
217
- initialOpen = { section . initialOpen }
218
- questions = { section . questions }
219
- onQuestionSelect = { setSelectedQuestionId }
220
- />
221
- ) ) }
217
+ < QuestionSection
218
+ title = '고정된 질문'
219
+ initialOpen = { true }
220
+ questions = { pinnedQuestions }
221
+ onQuestionSelect = { setSelectedQuestionId }
222
+ />
223
+ < QuestionSection
224
+ title = '질문'
225
+ initialOpen = { true }
226
+ questions = { unpinnedQuestions }
227
+ onQuestionSelect = { setSelectedQuestionId }
228
+ />
229
+ < QuestionSection
230
+ title = '답변 완료된 질문'
231
+ initialOpen = { false }
232
+ questions = { closedQuestions }
233
+ onQuestionSelect = { setSelectedQuestionId }
234
+ />
222
235
</ motion . div >
223
236
) }
224
237
{ CreateQuestion }
0 commit comments