Skip to content

Commit 13f909d

Browse files
committed
Get category dynamically
1 parent 4cbcfcd commit 13f909d

File tree

4 files changed

+201
-77
lines changed

4 files changed

+201
-77
lines changed

frontend/src/components/QuestionImageContainer/index.tsx

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Button, ImageList, ImageListItem } from "@mui/material";
55
import FileUploadIcon from "@mui/icons-material/FileUpload";
66
import { toast } from "react-toastify";
77

8-
import { questionClient } from "../../utils/api";
8+
import { createImageUrls } from "../../reducers/questionReducer";
99
import QuestionImage from "../QuestionImage";
1010
import QuestionImageDialog from "../QuestionImageDialog";
1111

@@ -64,23 +64,16 @@ const QuestionImageContainer: React.FC<QuestionImageContainerProps> = ({
6464
return;
6565
}
6666

67-
try {
68-
const response = await questionClient.post("/images", formData, {
69-
headers: {
70-
"Content-Type": "multipart/form-data",
71-
},
72-
withCredentials: false,
73-
});
74-
75-
const data = response.data;
76-
for (const imageUrl of data.imageUrls) {
77-
setUploadedImagesUrl((prev) => [...prev, imageUrl]);
67+
createImageUrls(formData).then((res) => {
68+
if (res) {
69+
for (const imageUrl of res.imageUrls) {
70+
setUploadedImagesUrl((prev) => [...prev, imageUrl]);
71+
}
72+
toast.success("File uploaded successfully");
73+
} else {
74+
toast.error("Error uploading file");
7875
}
79-
80-
toast.success("File uploaded successfully");
81-
} catch {
82-
toast.error("Error uploading file");
83-
}
76+
});
8477
};
8578

8679
if (uploadedImagesUrl.length === 0) {

frontend/src/pages/NewQuestion/index.tsx

Lines changed: 58 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,20 @@
1-
import { useState } from "react";
1+
import { useState, useReducer } from "react";
22
import { useNavigate } from "react-router-dom";
3-
import { Autocomplete, Button, IconButton, Stack, TextField } from "@mui/material";
3+
import {
4+
Autocomplete,
5+
Button,
6+
IconButton,
7+
Stack,
8+
TextField,
9+
} from "@mui/material";
410
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
5-
import axios from "axios";
11+
import reducer, {
12+
createQuestion,
13+
initialState,
14+
} from "../../reducers/questionReducer";
615
import { ToastContainer, toast } from "react-toastify";
716
import "react-toastify/dist/ReactToastify.css";
817

9-
import { questionClient } from "../../utils/api";
1018
import { complexityList } from "../../utils/constants";
1119
import AppMargin from "../../components/AppMargin";
1220
import QuestionMarkdown from "../../components/QuestionMarkdown";
@@ -17,52 +25,60 @@ import QuestionDetail from "../../components/QuestionDetail";
1725
const NewQuestion = () => {
1826
const navigate = useNavigate();
1927

28+
const [state, dispatch] = useReducer(reducer, initialState);
29+
2030
const [title, setTitle] = useState<string>("");
2131
const [markdownText, setMarkdownText] = useState<string>("");
22-
const [selectedComplexity, setselectedComplexity] = useState<string | null>(null);
32+
const [selectedComplexity, setselectedComplexity] = useState<string | null>(
33+
null
34+
);
2335
const [selectedCategories, setSelectedCategories] = useState<string[]>([]);
2436
const [uploadedImagesUrl, setUploadedImagesUrl] = useState<string[]>([]);
2537
const [isPreviewQuestion, setIsPreviewQuestion] = useState<boolean>(false);
2638

2739
const handleBack = () => {
28-
if (title || markdownText || selectedComplexity || selectedCategories.length > 0) {
29-
if (!confirm("Are you sure you want to leave this page? All process will be lost.")) {
40+
if (
41+
title ||
42+
markdownText ||
43+
selectedComplexity ||
44+
selectedCategories.length > 0
45+
) {
46+
if (
47+
!confirm(
48+
"Are you sure you want to leave this page? All process will be lost."
49+
)
50+
) {
3051
return;
3152
}
3253
}
3354
navigate("/questions");
3455
};
3556

3657
const handleSubmit = async () => {
37-
if (!title || !markdownText || !selectedComplexity || selectedCategories.length === 0) {
58+
if (
59+
!title ||
60+
!markdownText ||
61+
!selectedComplexity ||
62+
selectedCategories.length === 0
63+
) {
3864
toast.error("Please fill in all fields");
3965
return;
4066
}
4167

42-
try {
43-
await questionClient.post(
44-
"/",
45-
{
46-
title,
47-
description: markdownText,
48-
complexity: selectedComplexity,
49-
category: selectedCategories,
50-
},
51-
{
52-
withCredentials: false,
53-
headers: {
54-
"Content-Type": "application/json",
55-
},
56-
}
57-
);
68+
const result = await createQuestion(
69+
{
70+
title,
71+
description: markdownText,
72+
complexity: selectedComplexity,
73+
categories: selectedCategories,
74+
},
75+
dispatch
76+
);
77+
78+
if (result) {
5879
navigate("/questions");
59-
} catch (error) {
60-
if (axios.isAxiosError(error)) {
61-
const message = error.response?.data.message || "Failed to create question";
62-
toast.error(message);
63-
} else {
64-
toast.error("Failed to create question");
65-
}
80+
} else {
81+
toast.error(state.selectedQuestionError || "Failed to create question");
6682
}
6783
};
6884

@@ -99,7 +115,9 @@ const NewQuestion = () => {
99115
onChange={(e, newcomplexitySelected) => {
100116
setselectedComplexity(newcomplexitySelected);
101117
}}
102-
renderInput={(params) => <TextField {...params} label="Complexity" />}
118+
renderInput={(params) => (
119+
<TextField {...params} label="Complexity" />
120+
)}
103121
/>
104122

105123
<QuestionCategoryAutoComplete
@@ -112,7 +130,10 @@ const NewQuestion = () => {
112130
setUploadedImagesUrl={setUploadedImagesUrl}
113131
/>
114132

115-
<QuestionMarkdown markdownText={markdownText} setMarkdownText={setMarkdownText} />
133+
<QuestionMarkdown
134+
markdownText={markdownText}
135+
setMarkdownText={setMarkdownText}
136+
/>
116137
</>
117138
)}
118139

@@ -125,7 +146,10 @@ const NewQuestion = () => {
125146
color="secondary"
126147
fullWidth
127148
disabled={
128-
!title && !markdownText && !selectedComplexity && selectedCategories.length === 0
149+
!title &&
150+
!markdownText &&
151+
!selectedComplexity &&
152+
selectedCategories.length === 0
129153
}
130154
onClick={() => setIsPreviewQuestion((prev) => !prev)}
131155
>

frontend/src/pages/QuestionEdit/index.tsx

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@ import {
88
TextField,
99
} from "@mui/material";
1010
import ArrowBackIcon from "@mui/icons-material/ArrowBack";
11-
import axios from "axios";
1211
import { ToastContainer, toast } from "react-toastify";
1312
import "react-toastify/dist/ReactToastify.css";
1413

15-
import { questionClient } from "../../utils/api";
1614
import { complexityList } from "../../utils/constants";
1715
import reducer, {
1816
getQuestionById,
17+
updateQuestionById,
1918
initialState,
2019
} from "../../reducers/questionReducer";
2120
import AppMargin from "../../components/AppMargin";
@@ -82,32 +81,31 @@ const QuestionEdit = () => {
8281
return;
8382
}
8483

85-
try {
86-
await questionClient.put(
87-
`/${state.selectedQuestion.id}`,
88-
{
89-
title,
90-
description: markdownText,
91-
complexity: selectedComplexity,
92-
category: selectedCategories,
93-
},
94-
{
95-
withCredentials: false,
96-
headers: {
97-
"Content-Type": "application/json",
98-
},
99-
}
100-
);
84+
if (
85+
!title ||
86+
!markdownText ||
87+
!selectedComplexity ||
88+
selectedCategories.length === 0
89+
) {
90+
toast.error("Please fill in all fields");
91+
return;
92+
}
10193

94+
const result = await updateQuestionById(
95+
state.selectedQuestion.id,
96+
{
97+
title,
98+
description: markdownText,
99+
complexity: selectedComplexity,
100+
categories: selectedCategories,
101+
},
102+
dispatch
103+
);
104+
105+
if (result) {
102106
navigate("/questions");
103-
} catch (error) {
104-
if (axios.isAxiosError(error)) {
105-
const message =
106-
error.response?.data.message || "Failed to update question";
107-
toast.error(message);
108-
} else {
109-
toast.error("Failed to update question");
110-
}
107+
} else {
108+
toast.error(state.selectedQuestionError || "Failed to update question");
111109
}
112110
};
113111

0 commit comments

Comments
 (0)