Skip to content

Commit 99598fe

Browse files
committed
Update UI for EditQn (categories)
1 parent 0207b5b commit 99598fe

File tree

1 file changed

+170
-32
lines changed

1 file changed

+170
-32
lines changed

Frontend/src/components/question/EditQn.jsx

Lines changed: 170 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,95 @@
11
import React from 'react'
2-
import { useState } from 'react'
2+
import { useState, useEffect } from 'react'
33
import questionService from "../../services/questions"
4+
import categoryService from "../../services/categories"
45

56
function EditQn({ question, handleClose, editQuestion }) {
6-
const [category, setCategory] = useState(question.category);
7+
const [categories, setCategories] = useState(question.category);
8+
const [categoryInput, setCategoryInput] = useState('');
9+
const [categoriesFromDB, setCategoriesFromDB] = useState([]);
710
const [complexity, setComplexity] = useState(question.complexity);
811
const [description, setDescription] = useState(question.description);
912
const [title, setTitle] = useState(question.title);
1013
const [error, setError] = useState(null);
1114

15+
useEffect(() => {
16+
categoryService.getAllCategories()
17+
.then(result => {
18+
// console.log("API call successful. Result:", result);
19+
setCategoriesFromDB(Array.isArray(result) ? result : []);
20+
// console.log("categoriesFromDB after set:", categoriesFromDB);
21+
})
22+
.catch(err => console.log("Error fetching categories:", err));
23+
}, []);
24+
25+
const handleCategoryInputChange = (e) => {
26+
setCategoryInput(e.target.value);
27+
};
28+
29+
const handleAddCategory = () => {
30+
if (categoryInput && !categories.includes(categoryInput)) {
31+
setCategories([...categories, categoryInput]);
32+
}
33+
console.log(`categories are: ${categories}`);
34+
setCategoryInput('');
35+
};
36+
37+
const handleCategorySelect = (suggestion) => {
38+
if (!categories.includes(suggestion.name)) {
39+
setCategories([...categories, suggestion.name]);
40+
}
41+
setCategoryInput('');
42+
};
43+
44+
const handleRemoveCategory = (categoryToRemove) => {
45+
setCategories(categories.filter((category) => category !== categoryToRemove));
46+
};
47+
1248
const Update = (e) => {
1349
e.preventDefault();
50+
console.log("updated categories:", categories)
51+
const updatedQuestion = {
52+
category: categories,
53+
complexity,
54+
description,
55+
title,
56+
};
57+
console.log("updated qn", updatedQuestion)
1458

15-
// To remove empty strings and extra spaces
16-
const delimeter = ", "
17-
const categoryString = category.join(delimeter);
18-
const cleanedCategoryArray = categoryString.split(delimeter).filter(item => item.trim() !== "");
59+
const dbTopicNames = categoriesFromDB.map(cat => cat.name);
60+
const newCategories = categories.filter(item => !dbTopicNames.includes(item));
61+
console.log(`newCategories are ${newCategories}`);
1962

20-
const updatedQuestion = {
21-
category: cleanedCategoryArray,
22-
complexity,
23-
description,
24-
title,
63+
categoryService.createCategories(newCategories)
64+
.then(result => console.log(result.data))
65+
.catch(e => {
66+
if (e.response && e.response.status === 400) {
67+
setError(e.response.data.error);
68+
}
69+
console.error('Error updating category:', e);
70+
});
71+
72+
questionService.updateQuestion(question._id, updatedQuestion)
73+
.then(result => {
74+
75+
editQuestion(question._id, updatedQuestion);
76+
console.log('Question edited successfully:', result)
77+
handleClose();
78+
})
79+
.catch(e => {
80+
if (e.response && e.response.status === 400) {
81+
setError(e.response.data.error)
82+
// console.log("error is:", error)
83+
}
84+
console.error('Error updating question:', e);
85+
});
2586
};
26-
console.log("category array: ", cleanedCategoryArray)
27-
console.log("db_id:", question._id)
28-
console.log(category, complexity, description, title);
29-
30-
questionService.updateQuestion(question._id, updatedQuestion)
31-
.then(result => {
32-
33-
editQuestion(question._id, updatedQuestion);
34-
console.log('Question edited successfully:', result)
35-
handleClose();
36-
})
37-
.catch(e => {
38-
if (e.response && e.response.status === 400) {
39-
setError(e.response.data.error)
40-
// console.log("error is:", error)
41-
}
42-
console.error('Error updating question:', e);
43-
});
44-
};
87+
88+
const filteredSuggestions = Array.isArray(categoriesFromDB)
89+
? categoriesFromDB.filter(suggestion =>
90+
suggestion.name.toLowerCase().includes(categoryInput.toLowerCase())
91+
)
92+
: [];
4593

4694
return (
4795
<div className='d-flex bg-primary justify-content-center align-items-center'>
@@ -55,8 +103,98 @@ function EditQn({ question, handleClose, editQuestion }) {
55103
</div>
56104
<div className="mb-2">
57105
<label htmlFor="">Category</label>
58-
<input type="text" placeholder='Data Structures' className='form-control'
59-
value={category.join(",")} onChange={(e) => setCategory(e.target.value.split(","))}/>
106+
<input
107+
type="text"
108+
placeholder='Find or create a category'
109+
className='form-control'
110+
value={categoryInput}
111+
onChange={handleCategoryInputChange}
112+
onKeyDown={(e) => e.key === 'Enter' && (e.preventDefault(), handleAddCategory())}
113+
/>
114+
115+
{/* Outer container with rounded corners and border */}
116+
{categoryInput && (
117+
<div style={{
118+
border: "1px solid #ccc",
119+
borderRadius: "6px",
120+
paddingTop: "2px",
121+
marginTop: "5px",
122+
maxWidth: "100%",
123+
}}>
124+
{/* Scrollable inner container for suggestion items */}
125+
<div style={{
126+
maxHeight: "150px", // Approx height for 3 items
127+
overflowY: "auto", // Scrollbar only if > 3 items
128+
overflowX: "hidden",
129+
}}>
130+
{filteredSuggestions.map((suggestion, index) => (
131+
<li
132+
key={index}
133+
onClick={() => handleCategorySelect(suggestion)}
134+
style={{
135+
cursor: 'pointer',
136+
padding: "10px 10px",
137+
margin: "0px 10px",
138+
backgroundColor: "#fff",
139+
display: "flex",
140+
alignItems: "center",
141+
transition: "background-color 0.2s",
142+
borderBottom: index === filteredSuggestions.length - 1 ? "none" : "1px solid #e0e0e0"
143+
}}
144+
onMouseOver={(e) => e.currentTarget.style.backgroundColor = "#f1f3f5"}
145+
onMouseOut={(e) => e.currentTarget.style.backgroundColor = "#fff"}
146+
>
147+
<span style={{ color: "#28a745", marginRight: "8px" }}>+</span>
148+
{suggestion.name}
149+
</li>
150+
))}
151+
</div>
152+
153+
{/* "New category" item */}
154+
{!filteredSuggestions.some(suggestion => suggestion.name.toLowerCase() === categoryInput.toLowerCase()) && (
155+
<li
156+
onClick={handleAddCategory}
157+
style={{
158+
cursor: 'pointer',
159+
padding: "10px 15px",
160+
fontStyle: 'italic',
161+
color: 'gray',
162+
backgroundColor: "#fff",
163+
display: "flex",
164+
alignItems: "center",
165+
transition: "background-color 0.2s",
166+
borderTop: "1px solid #e0e0e0", // Border above if there are suggestions
167+
borderBottomRightRadius: "6px",
168+
borderBottomLeftRadius: "6px",
169+
}}
170+
onMouseOver={(e) => e.currentTarget.style.backgroundColor = "#f1f3f5"}
171+
onMouseOut={(e) => e.currentTarget.style.backgroundColor = "#fff"}
172+
>
173+
New category: "{categoryInput}". Press Enter to add.
174+
</li>
175+
)}
176+
</div>
177+
)}
178+
179+
{/* Display selected categories as tags */}
180+
<div style={{ marginTop: '10px' }}>
181+
{categories.map((category, index) => (
182+
<span
183+
key={index}
184+
style={{
185+
display: 'inline-block',
186+
padding: '5px',
187+
margin: '5px',
188+
backgroundColor: '#e0e0e0',
189+
borderRadius: '5px',
190+
cursor: 'pointer'
191+
}}
192+
onClick={() => handleRemoveCategory(category)}
193+
>
194+
{category} &times;
195+
</span>
196+
))}
197+
</div>
60198
</div>
61199
<div className="container my-3">
62200
<h5>Complexity</h5>

0 commit comments

Comments
 (0)