1
1
import React , { useState , useCallback , useEffect , useRef } from "react" ;
2
+ import { CodeEditorHandle } from "../../presentation/components/CodeEditor/CodeEditor" ;
2
3
import styles from "./CollaborationRoomPage.module.css" ;
3
4
import CodeEditor from "../../presentation/components/CodeEditor/CodeEditor" ;
4
5
import { QuestionDetail } from "../../presentation/components/QuestionDetail" ;
@@ -15,6 +16,7 @@ import { Room } from "../../domain/entities/Room";
15
16
import { useAuth } from "../../domain/context/AuthContext" ;
16
17
import { Spin } from "antd" ;
17
18
import { toast } from "react-toastify" ;
19
+ import { historyUseCases } from "domain/usecases/HistoryUseCases" ;
18
20
19
21
const CollaborationRoomPage : React . FC = ( ) => {
20
22
const location = useLocation ( ) ;
@@ -23,12 +25,15 @@ const CollaborationRoomPage: React.FC = () => {
23
25
24
26
// State Definitions
25
27
const { urlRoomId } = useParams < { urlRoomId : string } > ( ) ;
26
- const [ room , setRoom ] = useState < Room | null > ( null ) ;
28
+ const [ hasUserConfirmedLeave , setHasUserConfirmedLeave ] = useState ( false ) ;
29
+ const [ shouldSaveOnLeave , setShouldSaveOnLeave ] = useState ( true ) ;
30
+ const [ room , setRoom ] = useState < Room > ( ) ;
27
31
const [ question , setQuestion ] = useState < Question | undefined > ( undefined ) ;
28
32
const [ showChat , setShowChat ] = useState ( false ) ;
29
33
const [ loading , setLoading ] = useState < boolean > ( true ) ;
30
34
const [ error , setError ] = useState < string | null > ( null ) ;
31
35
const resizeTimeoutRef = useRef < NodeJS . Timeout > ( ) ;
36
+ const codeEditorRef = useRef < CodeEditorHandle > ( null ) ;
32
37
33
38
// Extract details from location.state if available
34
39
const { roomId, attemptStartedAt, matchUserId, questionId } = locationState || { } ;
@@ -111,7 +116,68 @@ const CollaborationRoomPage: React.FC = () => {
111
116
if ( resizeTimeoutRef . current ) clearTimeout ( resizeTimeoutRef . current ) ;
112
117
} ;
113
118
} , [ handleResize ] ) ;
119
+
120
+
121
+ useEffect ( ( ) => {
122
+
123
+ const saveAttempt = async ( ) => {
124
+ if ( hasUserConfirmedLeave ) {
125
+ if ( ! shouldSaveOnLeave ) return ; // User chose not to save
126
+ }
127
+
128
+ // Attempt to save
129
+ try {
130
+ if ( ! room ) return ;
131
+ await historyUseCases . createOrUpdateUserHistory (
132
+ room . questionId ,
133
+ room . roomId ,
134
+ new Date ( room . attemptStartedAt ) . getTime ( ) . toString ( ) ,
135
+ Date . now ( ) . toString ( ) ,
136
+ room . userIdTwo ?. _id ,
137
+ codeEditorRef . current ?. getEditorText ( ) || "" ,
138
+ ) ;
139
+ console . log ( "Attempt saved successfully." ) ;
140
+ } catch ( error ) {
141
+ console . error ( "Failed to save attempt on unmount:" , error ) ;
142
+ }
143
+ } ;
144
+
145
+ return ( ) => {
146
+ saveAttempt ( ) ;
147
+ } ;
148
+ } , [ hasUserConfirmedLeave , room , shouldSaveOnLeave ] ) ;
149
+
150
+ useEffect ( ( ) => {
151
+
152
+ const saveAttemptAsync = async ( ) => {
153
+ if ( ! room ) return ;
154
+ if ( hasUserConfirmedLeave ) {
155
+ if ( ! shouldSaveOnLeave ) return ;
156
+ }
157
+
158
+ const editorContent = codeEditorRef . current ?. getEditorText ( ) || "" ;
159
+ await historyUseCases . createOrUpdateUserHistory (
160
+ room . questionId ,
161
+ room . roomId ,
162
+ new Date ( room . attemptStartedAt ) . getTime ( ) . toString ( ) ,
163
+ Date . now ( ) . toString ( ) ,
164
+ room . userIdTwo ?. _id ,
165
+ editorContent ,
166
+ ) ;
167
+ } ;
114
168
169
+ const handleBeforeUnload = async ( event : BeforeUnloadEvent ) => {
170
+ await saveAttemptAsync ( ) ;
171
+ } ;
172
+
173
+ window . addEventListener ( 'beforeunload' , handleBeforeUnload ) ;
174
+
175
+ return ( ) => {
176
+ window . removeEventListener ( 'beforeunload' , handleBeforeUnload ) ;
177
+ } ;
178
+ } , [ hasUserConfirmedLeave , room , shouldSaveOnLeave ] ) ;
179
+
180
+
115
181
// Resizable Layout Configurations
116
182
const { position : questionPosition , separatorProps : verticalSeparatorProps } = useResizable ( {
117
183
axis : "x" ,
@@ -164,10 +230,15 @@ const CollaborationRoomPage: React.FC = () => {
164
230
< div className = { styles . editorAndOutputContainer } >
165
231
< div className = { styles . editorContainer } >
166
232
< CodeEditor
233
+ ref = { codeEditorRef }
167
234
questionId = { room . questionId }
168
235
roomId = { room . roomId }
169
236
attemptStartedAt = { new Date ( room . attemptStartedAt ) }
170
237
collaboratorId = { room . userIdTwo ?. _id }
238
+ onUserConfirmedLeave = { ( shouldSave : boolean ) => {
239
+ setHasUserConfirmedLeave ( true ) ;
240
+ setShouldSaveOnLeave ( shouldSave ) ;
241
+ } }
171
242
/>
172
243
</ div >
173
244
0 commit comments