1
1
import React , { useState , useEffect } from 'react' ;
2
2
import Modal from "react-bootstrap/Modal" ;
3
- import Table from "react-bootstrap/Table" ;
4
3
import ButtonGroup from "react-bootstrap/ButtonGroup" ;
5
4
import CreateQn from "./CreateQn" ;
6
5
import EditQn from "./EditQn" ;
6
+ import DetailQn from "./DetailQn" ;
7
7
import questionService from "../../services/questions"
8
8
import userService from "../../services/users" ;
9
9
import categoryService from "../../services/categories" ;
10
-
10
+ import { AgGridReact } from 'ag-grid-react' ; // React Data Grid Component
11
+ import "ag-grid-community/styles/ag-grid.css" ; // Mandatory CSS required by the Data Grid
12
+ import "ag-grid-community/styles/ag-theme-quartz.css" ; // Optional Theme applied to the Data Grid
11
13
12
14
function Question ( ) {
13
15
const [ questions , setQuestions ] = useState ( [ ] ) ;
14
16
const [ showComponent , setShowComponent ] = useState ( false ) ;
15
17
const [ showDeleteModal , setShowDeleteModal ] = useState ( false ) ;
16
18
const [ questionToDelete , setQuestionToDelete ] = useState ( null ) ;
17
19
const [ showEditModal , setShowEditModal ] = useState ( false ) ;
20
+ const [ showDetailModal , setShowDetailModal ] = useState ( false ) ;
18
21
const [ currentQuestion , setCurrentQuestion ] = useState ( null ) ;
19
22
const [ isAdmin , setIsAdmin ] = useState ( false ) ;
20
23
@@ -50,16 +53,20 @@ function Question() {
50
53
console . log ( 'Error:' , e ) ;
51
54
} ) ;
52
55
} , [ ] ) ;
53
-
54
- const easyQuestions = questions . filter ( q => q . complexity === "Easy" )
55
- const mediumQuestions = questions . filter ( q => q . complexity === "Medium" )
56
- const hardQuestions = questions . filter ( q => q . complexity === "Hard" )
57
56
58
57
const addQuestion = ( newQuestion ) => {
59
58
setQuestions ( ( prevQuestions ) => [ ...prevQuestions , newQuestion ] ) ;
60
59
} ;
61
60
62
-
61
+ const handleShowDetailModal = ( question ) => {
62
+ setCurrentQuestion ( question ) ;
63
+ setShowDetailModal ( true ) ;
64
+ }
65
+
66
+ const handleCloseDetailModal = ( ) => {
67
+ setShowDetailModal ( false ) ;
68
+ }
69
+
63
70
const editQuestion = ( id , updatedQuestion ) => {
64
71
const updatedQuestions = questions . map ( ( q ) =>
65
72
q . _id === id ? { ...q , ...updatedQuestion } : q
@@ -128,52 +135,82 @@ function Question() {
128
135
} ;
129
136
130
137
131
- const renderQuestionsTable = ( questions ) => {
132
- const sortedQuestions = [ ...questions ] . sort ( ( a , b ) => a . id - b . id )
138
+ const renderQuestionsTable = ( ) => {
139
+ const editDeleteButtonComponent = ( props ) => {
140
+ const question = props . data ;
141
+ return (
142
+ < ButtonGroup className = "container-fluid mt-1 mb-1" >
143
+ < button
144
+ className = 'btn btn-success btn-sm'
145
+ onClick = { ( ) => handleShowEditModal ( question ) }
146
+ >
147
+ Edit
148
+ </ button >
149
+ < button className = 'btn btn-danger btn-sm' size = "sm"
150
+ onClick = { ( ) => handleShowDelete ( question . _id ) } >
151
+ Delete
152
+ </ button >
153
+ </ ButtonGroup >
154
+ ) ;
155
+ } ;
133
156
157
+ const showDetailButtonComponent = ( props ) => {
158
+ const question = props . data ;
159
+ return (
160
+ < ButtonGroup className = "container-fluid mt-1 mb-1" >
161
+ < button
162
+ className = 'btn btn-info btn-sm'
163
+ onClick = { ( ) => handleShowDetailModal ( question ) }
164
+ >
165
+ Show Details
166
+ </ button >
167
+ </ ButtonGroup >
168
+ ) ;
169
+ } ;
170
+
171
+ const colDefs = [
172
+ { field : "id" , flex : 1 , wrapText : true , sort : "asc" } ,
173
+ { field : "title" , flex : 4 , wrapText : true } ,
174
+ { field : "category" , flex : 3 , autoHeight : true , cellDataType : 'text' } ,
175
+ {
176
+ field : "complexity" ,
177
+ flex : 1.5 ,
178
+ comparator : ( valueA , valueB ) => {
179
+ if ( valueA === valueB ) return 0 ;
180
+ if ( valueA === "Easy" || valueB === "Hard" ) return - 1 ;
181
+ if ( valueA === "Hard" || valueB === "Easy" ) return 1 ;
182
+ }
183
+ } ,
184
+ {
185
+ field : "details" ,
186
+ width : 200 ,
187
+ resizable : false ,
188
+ sortable : false ,
189
+ cellRenderer : showDetailButtonComponent } ,
190
+ ...( isAdmin ? [ {
191
+ field : "action" ,
192
+ width : 200 ,
193
+ resizable : false ,
194
+ sortable : false ,
195
+ cellRenderer : editDeleteButtonComponent
196
+ } ] : [ ] )
197
+ ] ;
198
+
134
199
return (
135
- < Table >
136
- < thead >
137
- < tr >
138
- < th > ID</ th >
139
- < th > Title</ th >
140
- < th > Description</ th >
141
- < th > Category</ th >
142
- { isAdmin && ( < th > Action</ th > ) }
143
- </ tr >
144
- </ thead >
145
- < tbody >
146
- { sortedQuestions . map ( ( question ) => (
147
- < tr key = { question . id } >
148
- < td > { question . id } </ td >
149
- < td > { question . title } </ td >
150
- < td > { question . description } </ td >
151
- < td > { question . category ? question . category . join ( ", " ) : '' } </ td >
152
- { isAdmin && (
153
- < td >
154
- < ButtonGroup className = "mb-2" >
155
- < button
156
- className = 'btn btn-success'
157
- onClick = { ( ) => handleShowEditModal ( question ) }
158
- >
159
- Edit
160
- </ button >
161
- < button className = 'btn btn-danger' size = "sm"
162
- onClick = { ( ) => handleShowDelete ( question . _id ) } >
163
- Delete
164
- </ button >
165
- </ ButtonGroup >
166
- </ td >
167
- ) }
168
- </ tr >
169
- ) ) }
170
- </ tbody >
171
- </ Table >
200
+ < div
201
+ className = "container-fluid ag-theme-quartz"
202
+ style = { { height : 500 } }
203
+ >
204
+ < AgGridReact
205
+ rowData = { questions }
206
+ columnDefs = { colDefs }
207
+ />
208
+ </ div >
172
209
) ;
173
210
} ;
174
211
175
212
return (
176
- < div className = "d-flex " >
213
+ < div className = "container-fluid " >
177
214
< div className = 'bg-white rounded p-3 m-3' >
178
215
< div className = "d-flex justify-content-between" >
179
216
< h1 > Questions</ h1 >
@@ -194,14 +231,7 @@ function Question() {
194
231
< hr />
195
232
196
233
< div className = "container" >
197
- < h2 className = "p-2" > Easy Questions</ h2 >
198
- { renderQuestionsTable ( easyQuestions ) }
199
-
200
- < h2 className = "p-2" > Medium Questions</ h2 >
201
- { renderQuestionsTable ( mediumQuestions ) }
202
-
203
- < h2 className = "p-2" > Hard Questions</ h2 >
204
- { renderQuestionsTable ( hardQuestions ) }
234
+ { renderQuestionsTable ( ) }
205
235
206
236
{ /* Edit Modal */ }
207
237
< Modal show = { showEditModal } onHide = { handleCloseEditModal } backdrop = "static" >
@@ -217,6 +247,19 @@ function Question() {
217
247
</ Modal . Body >
218
248
</ Modal >
219
249
250
+ { /* Detail Modal */ }
251
+ < Modal show = { showDetailModal } onHide = { handleCloseDetailModal } backdrop = "static" >
252
+ < Modal . Header closeButton >
253
+ < Modal . Title > Question Details</ Modal . Title >
254
+ </ Modal . Header >
255
+ < Modal . Body >
256
+ < DetailQn
257
+ question = { currentQuestion }
258
+ handleClose = { handleCloseDetailModal }
259
+ />
260
+ </ Modal . Body >
261
+ </ Modal >
262
+
220
263
221
264
< Modal show = { showDeleteModal } onHide = { handleCloseDelete } centered >
222
265
< Modal . Body className = "text-center" >
0 commit comments