Skip to content

Commit ee596a5

Browse files
committed
Fix question table formatting and add button to see question details
1 parent 8e97071 commit ee596a5

File tree

2 files changed

+137
-44
lines changed

2 files changed

+137
-44
lines changed
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React from 'react'
2+
import { useState, useEffect } from 'react'
3+
4+
function DetailQn({ question, handleClose }) {
5+
const [categories, setCategories] = useState(question.category);
6+
const [complexity, setComplexity] = useState(question.complexity);
7+
const [description, setDescription] = useState(question.description);
8+
const [title, setTitle] = useState(question.title);
9+
const [error, setError] = useState(null);
10+
11+
return (
12+
<div className='d-flex bg-primary justify-content-center align-items-center'>
13+
<div className="w-100 bg-white px-3 pb-3">
14+
{error && <div className="alert alert-danger">{error}</div>}
15+
<div className="mb-2">
16+
<b>Title</b>
17+
<div className="mt-1">
18+
<p>{title}</p>
19+
</div>
20+
</div>
21+
<div className="mb-2">
22+
<b>Category</b>
23+
24+
{/* Display selected categories as tags */}
25+
<div style={{ marginTop: '5px' }}>
26+
{categories.map((category, index) => (
27+
<span
28+
key={index}
29+
style={{
30+
display: 'inline-block',
31+
padding: '5px',
32+
margin: '5px',
33+
backgroundColor: '#e0e0e0',
34+
borderRadius: '5px'
35+
}}
36+
>
37+
{category}
38+
</span>
39+
))}
40+
</div>
41+
</div>
42+
<b>Complexity</b>
43+
<div className="mt-1">
44+
<p>{complexity}</p>
45+
</div>
46+
<div className="mb-3">
47+
<b>Description</b>
48+
<div className="mt-1">
49+
<p>{description}</p>
50+
</div>
51+
</div>
52+
</div>
53+
</div>
54+
)
55+
}
56+
57+
export default DetailQn

Frontend/src/components/question/Question.jsx

Lines changed: 80 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
import React, { useState, useEffect } from 'react';
22
import Modal from "react-bootstrap/Modal";
3-
import Table from "react-bootstrap/Table";
43
import ButtonGroup from "react-bootstrap/ButtonGroup";
54
import CreateQn from "./CreateQn";
65
import EditQn from "./EditQn";
6+
import DetailQn from "./DetailQn";
77
import questionService from "../../services/questions"
88
import userService from "../../services/users";
99
import categoryService from "../../services/categories";
@@ -17,6 +17,7 @@ function Question() {
1717
const [showDeleteModal, setShowDeleteModal] = useState(false);
1818
const [questionToDelete, setQuestionToDelete] = useState(null);
1919
const [showEditModal, setShowEditModal] = useState(false);
20+
const [showDetailModal, setShowDetailModal] = useState(false);
2021
const [currentQuestion, setCurrentQuestion] = useState(null);
2122
const [isAdmin, setIsAdmin] = useState(false);
2223

@@ -57,7 +58,15 @@ function Question() {
5758
setQuestions((prevQuestions) => [...prevQuestions, newQuestion]);
5859
};
5960

60-
61+
const handleShowDetailModal = (question) => {
62+
setCurrentQuestion(question);
63+
setShowDetailModal(true);
64+
}
65+
66+
const handleCloseDetailModal = () => {
67+
setShowDetailModal(false);
68+
}
69+
6170
const editQuestion = (id, updatedQuestion) => {
6271
const updatedQuestions = questions.map((q) =>
6372
q._id === id ? { ...q, ...updatedQuestion } : q
@@ -127,55 +136,69 @@ function Question() {
127136

128137

129138
const renderQuestionsTable = () => {
130-
const CustomButtonComponent = (props) => {
131-
const question = props.data
132-
return <ButtonGroup className="mb-2">
133-
<button
134-
className='btn btn-success'
135-
onClick={() => handleShowEditModal(question)}
136-
>
137-
Edit
138-
</button>
139-
<button className='btn btn-danger' size="sm"
140-
onClick={() => handleShowDelete(question._id)}>
141-
Delete
142-
</button>
143-
</ButtonGroup>
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+
);
144155
};
145156

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 Detail
166+
</button>
167+
</ButtonGroup>
168+
);
169+
};
170+
146171
const colDefs = [
147172
{ field: "id", flex: 1, wrapText: true, sort: "asc" },
148-
{ field: "title", flex: 2 },
149-
{ field: "description", flex: 5, wrapText: true, autoHeight: true},
150-
{ field: "complexity", flex: 1.5,
151-
comparator: (valueA, valueB, nodeA, nodeB, isDescending) => {
152-
if (valueA == valueB) return 0;
153-
if (valueA == "Easy" || valueB == "Hard") return -1;
154-
if (valueA == "Hard" || valueB == "Easy") return 1;
155-
}
156-
}
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+
...(isAdmin ? [{
185+
field: "action",
186+
width: 200,
187+
resizable: false,
188+
sortable: false,
189+
cellRenderer: editDeleteButtonComponent
190+
}] : [{
191+
field: "details",
192+
width: 200,
193+
resizable: false,
194+
sortable: false,
195+
cellRenderer: showDetailButtonComponent }])
157196
];
158-
159-
if (isAdmin) {
160-
colDefs = [
161-
{ field: "id", flex: 1, wrapText: true, sort: "asc" },
162-
{ field: "title", flex: 2 },
163-
{ field: "description", flex: 5, wrapText: true, autoHeight: true},
164-
{ field: "complexity", flex: 1.5,
165-
comparator: (valueA, valueB, nodeA, nodeB, isDescending) => {
166-
if (valueA == valueB) return 0;
167-
if (valueA == "Easy" || valueB == "Hard") return -1;
168-
if (valueA == "Hard" || valueB == "Easy") return 1;
169-
}
170-
},
171-
{ field: "action", width: 200, resizable: false, sortable: false, cellRenderer: CustomButtonComponent }
172-
];
173-
}
174-
197+
175198
return (
176199
<div
177-
className="container-fluid ag-theme-quartz" // applying the Data Grid theme
178-
style={{ height: 500 }} // the Data Grid will fill the size of the parent container
200+
className="container-fluid ag-theme-quartz"
201+
style={{ height: 500 }}
179202
>
180203
<AgGridReact
181204
rowData={questions}
@@ -223,6 +246,19 @@ function Question() {
223246
</Modal.Body>
224247
</Modal>
225248

249+
{/* Detail Modal */}
250+
<Modal show={showDetailModal} onHide={handleCloseDetailModal} backdrop="static">
251+
<Modal.Header closeButton>
252+
<Modal.Title>Question Details</Modal.Title>
253+
</Modal.Header>
254+
<Modal.Body>
255+
<DetailQn
256+
question={currentQuestion}
257+
handleClose={handleCloseDetailModal}
258+
/>
259+
</Modal.Body>
260+
</Modal>
261+
226262

227263
<Modal show={showDeleteModal} onHide={handleCloseDelete} centered>
228264
<Modal.Body className="text-center">

0 commit comments

Comments
 (0)