@@ -26,10 +26,21 @@ interface ReplyQnAPayload {
2626 question_id : number ;
2727 answer : string ;
2828}
29+ interface UpdateQnAPayload {
30+ question_id : number ;
31+ answer : string ;
32+ }
33+
34+ interface DeleteQnAPayload {
35+ question_id : number ;
36+ context ?: 'question' | 'reply' ;
37+ }
2938
3039const FORM_ID_PREFIXES = {
3140 COMMENT_EDIT : 'lesson-comment-edit-' ,
3241 COMMENT_REPLY : 'lesson-comment-reply-form-' ,
42+ QNA_EDIT : 'qna-edit-' ,
43+ QNA_REPLY : 'qna-reply-form-' ,
3344} ;
3445
3546const MODALS = {
@@ -39,10 +50,12 @@ const MODALS = {
3950
4051const ELEMENT_IDS = {
4152 COMMENT_TEXT_PREFIX : 'tutor-lesson-comment-text-' ,
53+ QNA_TEXT_PREFIX : 'tutor-qna-text-' ,
4254 REPLIES_LIST_CONTAINER : 'tutor-discussion-replies-list' ,
4355} ;
4456
4557const URL_PARAMS = {
58+ TAB : 'tab' ,
4659 ID : 'id' ,
4760 ORDER : 'order' ,
4861} ;
@@ -65,6 +78,8 @@ const discussionsPage = () => {
6578 qnaSingleActionMutation : null as MutationState < unknown , unknown > | null ,
6679 deleteQnAMutation : null as MutationState < unknown , unknown > | null ,
6780 replyQnAMutation : null as MutationState < unknown , unknown > | null ,
81+ updateQnAMutation : null as MutationState < unknown , UpdateQnAPayload > | null ,
82+ loadQnARepliesMutation : null as MutationState < unknown , unknown > | null ,
6883 currentAction : null as string | null ,
6984 currentQuestionId : null as number | null ,
7085 isSolved : false ,
@@ -139,7 +154,7 @@ const discussionsPage = () => {
139154
140155 // Q&A single action mutation (read, unread, solved, important, archived).
141156 this . qnaSingleActionMutation = this . query . useMutation ( this . qnaSingleAction , {
142- onSuccess : ( response , payload : QnASingleActionPayload ) => {
157+ onSuccess : ( _ , payload : QnASingleActionPayload ) => {
143158 const action = payload . qna_action ;
144159 if ( action === 'solved' ) {
145160 this . isSolved = ! this . isSolved ;
@@ -162,10 +177,16 @@ const discussionsPage = () => {
162177
163178 // Q&A delete mutation.
164179 this . deleteQnAMutation = this . query . useMutation ( this . deleteQnA , {
165- onSuccess : ( ) => {
166- const url = new URL ( window . location . href ) ;
167- url . searchParams . delete ( URL_PARAMS . ID ) ;
168- window . location . href = url . toString ( ) ;
180+ onSuccess : ( _ , payload ) => {
181+ if ( payload . context === 'reply' ) {
182+ toast . success ( __ ( 'Reply deleted successfully' , 'tutor' ) ) ;
183+ modal . closeModal ( MODALS . QNA_DELETE ) ;
184+ this . reloadReplies ( ) ;
185+ } else {
186+ const url = new URL ( window . location . href ) ;
187+ url . searchParams . delete ( URL_PARAMS . ID ) ;
188+ window . location . href = url . toString ( ) ;
189+ }
169190 } ,
170191 onError : ( error : Error ) => {
171192 toast . error ( convertToErrorMessage ( error ) ) ;
@@ -174,9 +195,33 @@ const discussionsPage = () => {
174195
175196 // Q&A reply mutation.
176197 this . replyQnAMutation = this . query . useMutation ( this . replyQnA , {
177- onSuccess : ( ) => {
198+ onSuccess : ( _ , payload ) => {
178199 toast . success ( __ ( 'Reply saved successfully' , 'tutor' ) ) ;
179- window . location . reload ( ) ;
200+ this . reloadReplies ( ) ;
201+ const formId = `${ FORM_ID_PREFIXES . QNA_REPLY } ${ payload . question_id } ` ;
202+ if ( form . hasForm ( formId ) ) {
203+ form . reset ( formId ) ;
204+ }
205+ } ,
206+ onError : ( error : Error ) => {
207+ toast . error ( convertToErrorMessage ( error ) ) ;
208+ } ,
209+ } ) ;
210+
211+ // Q&A update mutation.
212+ this . updateQnAMutation = this . query . useMutation ( this . updateQnA , {
213+ onSuccess : ( _ , payload ) => {
214+ toast . success ( __ ( 'Updated successfully' , 'tutor' ) ) ;
215+
216+ // Update DOM directly for immediate feedback
217+ const element = document . getElementById ( `${ ELEMENT_IDS . QNA_TEXT_PREFIX } ${ payload . question_id } ` ) ;
218+ if ( element ) {
219+ element . innerHTML = payload . answer ;
220+ }
221+
222+ if ( this . editingId === payload . question_id ) {
223+ this . setEditing ( null ) ;
224+ }
180225 } ,
181226 onError : ( error : Error ) => {
182227 toast . error ( convertToErrorMessage ( error ) ) ;
@@ -191,12 +236,14 @@ const discussionsPage = () => {
191236
192237 const url = new URL ( window . location . href ) ;
193238 const commentId = parseInt ( url . searchParams . get ( URL_PARAMS . ID ) || '0' ) ;
239+ const tab = url . searchParams . get ( URL_PARAMS . TAB ) || 'qna' ;
194240
195241 if ( ! commentId ) return ;
196242
197243 this . loadingReplies = true ;
198244 try {
199- const response = await wpAjaxInstance . post ( endpoints . LOAD_DISCUSSION_REPLIES , {
245+ const endpoint = tab === 'qna' ? endpoints . LOAD_QNA_REPLIES : endpoints . LOAD_COMMENT_REPLIES ;
246+ const response = await wpAjaxInstance . post ( endpoint , {
200247 comment_id : commentId ,
201248 order : this . repliesOrder ,
202249 } ) ;
@@ -234,14 +281,18 @@ const discussionsPage = () => {
234281 return wpAjaxInstance . post ( endpoints . QNA_SINGLE_ACTION , payload ) ;
235282 } ,
236283
237- deleteQnA ( payload : { question_id : number } ) {
284+ deleteQnA ( payload : DeleteQnAPayload ) {
238285 return wpAjaxInstance . post ( endpoints . DELETE_DASHBOARD_QNA , payload ) ;
239286 } ,
240287
241288 replyQnA ( payload : ReplyQnAPayload ) {
242289 return wpAjaxInstance . post ( endpoints . CREATE_UPDATE_QNA , payload ) ;
243290 } ,
244291
292+ updateQnA ( payload : UpdateQnAPayload ) {
293+ return wpAjaxInstance . post ( endpoints . UPDATE_QNA , payload ) ;
294+ } ,
295+
245296 async handleQnASingleAction ( questionId : number , action : string , extras : Record < string , string > = { } ) {
246297 this . currentAction = action ;
247298 this . currentQuestionId = questionId ;
@@ -278,15 +329,18 @@ const discussionsPage = () => {
278329 }
279330 } ,
280331
281- setEditing ( id : number | null ) {
332+ setEditing ( id : number | null , context = 'comment' ) {
333+ const prefix = context === 'qna' ? FORM_ID_PREFIXES . QNA_EDIT : FORM_ID_PREFIXES . COMMENT_EDIT ;
334+ const field = context === 'qna' ? 'answer' : 'comment' ;
335+
282336 this . editingId = id ;
283- const formId = id ? `${ FORM_ID_PREFIXES . COMMENT_EDIT } ${ id } ` : null ;
337+ const formId = id ? `${ prefix } ${ id } ` : null ;
284338 this . editingFormId = formId ;
285339
286340 if ( id && formId ) {
287341 this . $nextTick ?.( ( ) => {
288342 if ( form . hasForm ( formId ) ) {
289- form . setFocus ( formId , 'comment' ) ;
343+ form . setFocus ( formId , field ) ;
290344 }
291345 } ) ;
292346 }
0 commit comments