Skip to content

Commit

Permalink
Link question service api (#82)
Browse files Browse the repository at this point in the history
* Add initialization of database with question page

* Add api calls for CRUD operations

* Update code

* Link question service api with database for CRUD operations

* Bug fix

* Change naming for hard to difficult

---------

Co-authored-by: Zenith Yap <[email protected]>
  • Loading branch information
zenithyap and Zenith Yap authored Oct 31, 2023
1 parent 7339417 commit 3009087
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 130 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,17 @@ import * as QuestionSlice from "../../redux/reducers/Question/QuestionSlice"
import React from "react";
import { useNavigate } from "react-router-dom";

import axios from 'axios';

const QuestionCreator = () => {
// for dispatching actions
const dispatch = useDispatch()
const navigate = useNavigate()

const createQuestionMessage = "New question created!";
const patchQuestionMessage = "Question updated!";
const sameQuestionTitleMessage = "Question title already exists!"

// selectors
const currentQuestionId: string = useSelector(QuestionSlice.selectCurrentId)
const currentTitle: string = useSelector(QuestionSlice.selectCurrentTitle)
Expand All @@ -30,12 +36,75 @@ const QuestionCreator = () => {
var duplicateCategoryErrorText: string = ""
var duplicateCategoryError: boolean = false

// Adds new question
const postQuestionData = () => {
axios
.post(`https://api.peerprepgroup51sem1y2023.xyz/api/questions/`, {
category: currentCategories,
description: currentDescription,
complexity: currentComplexity,
title: currentTitle
})
.then((reponse) => {
const id = reponse.data._id;
dispatch(QuestionSlice.addNewQuestion(id));
openSuccessSnackbar(true);
})
.catch((error) => {
console.log(error)
const code = error.response.status;
if (code === 400) {
openErrorSnackbar(true);
giveSnackbarMsg(sameQuestionTitleMessage);
}
});
};

const handlePostQuestionData = () => {
postQuestionData();
giveSnackbarMsg(createQuestionMessage);
}

// Update current question
const patchQuestionData = () => {
axios
.patch(
`https://api.peerprepgroup51sem1y2023.xyz/api/questions/${currentQuestionId}`,
{
category: currentCategories,
complexity: currentComplexity,
description: currentDescription,
title: currentTitle
}
)
.then(() => {
openSuccessSnackbar(true);
dispatch(QuestionSlice.updateCurrentQuestion());
})
.catch((error) => {
})
};

const handlePatchQuestionData = () => {
patchQuestionData();
giveSnackbarMsg(patchQuestionMessage);
}

// lifecycle methods here

// for initializing default values for the question creator based on the first data entry
// will run only once!
useEffect(() => {
dispatch(QuestionSlice.initializeQuestionCreator())
axios({
method: "get",
url: `https://api.peerprepgroup51sem1y2023.xyz/api/questions`,
})
.then((response) => {
const data = response.data;
dispatch(QuestionSlice.initializeQuestionCreator(data));
})
.catch(() => {
});
}, [])

const attemptQuestion = () => {
Expand All @@ -61,9 +130,9 @@ const QuestionCreator = () => {
value={currentComplexity}
label="complexity"
onChange={(event: SelectChangeEvent) => { dispatch(QuestionSlice.updateCurrentComplexity(event.target.value)) }}>
<MenuItem value={"Easy"}>Easy</MenuItem>
<MenuItem value={"Medium"}>Medium</MenuItem>
<MenuItem value={"Hard"}>Hard</MenuItem>
<MenuItem value={"easy"}>Easy</MenuItem>
<MenuItem value={"medium"}>Medium</MenuItem>
<MenuItem value={"difficult"}>Difficult</MenuItem>
</Select>
</FormControl>

Expand Down Expand Up @@ -138,10 +207,9 @@ const QuestionCreator = () => {
giveSnackbarMsg("Question details updated.")
openSuccessSnackbar(true)
} else {
dispatch(QuestionSlice.addNewQuestion());
giveSnackbarMsg("New question created.")
openSuccessSnackbar(true)
//dispatch(QuestionSlice.clearQuestionCreator())
isAddQuestionButtonToggled
? handlePostQuestionData()
: handlePatchQuestionData();
}
}}>
<SaveIcon sx={{ color: "#F4C2C2", cursor: "pointer" }} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,41 @@ import { useDispatch, useSelector } from "react-redux";
import * as QuestionSlice from "../../../redux/reducers/Question/QuestionSlice";
import * as UserSlice from "../../../redux/reducers/User/UserSlice";

import axios from 'axios';

interface questionObject {
Id: string,
Title: string,
Categories: string[],
Complexity: string,
Description: string
_id: string,
title: string,
category: string[],
complexity: string,
description: string
}

const CustomList = () => {
const currentQuestionId: string = useSelector(QuestionSlice.selectCurrentId);

// Deletes current question
const deleteQuestion = () => {
axios.delete(`https://api.peerprepgroup51sem1y2023.xyz/api/questions/${currentQuestionId}`)
.then(() => {
dispatch(QuestionSlice.deleteQuestion(currentId));
})
.catch(() => {
});
}

//const [questions] = React.useState(localDatabase);
const questions: questionObject[] = useSelector(QuestionSlice.selectQuestionsData)
const currentId: string = useSelector(QuestionSlice.selectCurrentId)
const isUserAnAdmin: boolean = useSelector(UserSlice.isUserAnAdmin)

let additionalStackContainerStyle = {}
const dispatch = useDispatch()

return (
<List sx={Style.listStyle}>
{questions.map((question: questionObject) => {
if (question.Id === currentId) {
if (question._id === currentId) {
additionalStackContainerStyle = {
border: "2px solid pink"
}
Expand All @@ -36,28 +51,28 @@ const CustomList = () => {
return (
<ListItem onClick={() => {
dispatch(QuestionSlice.toggleAddQuestionButton(false))
dispatch(QuestionSlice.updateCurrentId(question.Id))
dispatch(QuestionSlice.updateCurrentId(question._id))
}}>
<Stack direction="column" sx={{ ...Style.stackContainerStyle, ...additionalStackContainerStyle }}>
<Stack direction="row" justifyContent="space-between">
<Stack direction="row" alignItems="center" sx={Style.questionHeadingsStyle}>
{questions.indexOf(question) + 1}. {question.Title}
<Chip label={question.Complexity} sx={Style.difficultyChipStyle}></Chip>
{questions.indexOf(question) + 1}. {question.title}
<Chip label={question.complexity} sx={Style.difficultyChipStyle}></Chip>
</Stack>
<Stack direction="row" justifyContent="flex-end">
{isUserAnAdmin ?
<Tooltip title="Delete">
<IconButton style={Style.iconButtonStyle} onClick={(ev) => {
ev.stopPropagation()
dispatch(QuestionSlice.deleteQuestion(question.Id))
deleteQuestion()
}}><DeleteIcon />
</IconButton>
</Tooltip> : <></>
}
</Stack>
</Stack>
<Stack direction="row" spacing={2} sx={{ marginLeft: "5%" }}>
{question.Categories.map((category) => <Chip label={category} sx={Style.categoryChipStyle}></Chip>)}
{question.category.map((category) => <Chip label={category} sx={Style.categoryChipStyle}></Chip>)}
</Stack>
</Stack>
</ListItem>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import React from "react";
import CustomList from "./CustomList/CustomList";

// import Redux stuff
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { useDispatch, useSelector } from "react-redux";
import * as QuestionSlice from "../../redux/reducers/Question/QuestionSlice"
import { useNavigate } from "react-router-dom";

import axios from 'axios';

const QuestionViewer = () => {
// for dispatching actions
const dispatch = useDispatch()
Expand All @@ -19,7 +21,16 @@ const QuestionViewer = () => {
// for initializing default values for the question creator based on the first data entry
// will run only once!
useEffect(() => {
dispatch(QuestionSlice.initializeQuestionCreator())
axios({
method: "get",
url: `https://api.peerprepgroup51sem1y2023.xyz/api/questions`,
})
.then((response) => {
const data = response.data;
dispatch(QuestionSlice.initializeQuestionCreator(data));
})
.catch(() => {
});
}, [])

const attemptQuestion = () => {
Expand Down
21 changes: 21 additions & 0 deletions front-end/peer-prep/src/components/QuestionsPage/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
import React from "react";
import { useEffect } from "react";

import { useDispatch } from "react-redux";
import * as QuestionSlice from "../redux/reducers/Question/QuestionSlice"

// import components
import QuestionCreator from "./QuestionCreator";
Expand All @@ -10,7 +14,24 @@ import { useSelector } from "react-redux/es/hooks/useSelector";
// import styles
import { questionPageContainerStyle } from "./styles";

import axios from 'axios';

const QuestionsPage = () => {
const dispatch = useDispatch();

useEffect(() => {
axios({
method: "get",
url: `https://api.peerprepgroup51sem1y2023.xyz/api/questions`,
})
.then((response) => {
const data = response.data;
dispatch(QuestionSlice.initializeQuestionData(data));
})
.catch(() => {
});
}, []);

const htmlElement = document.documentElement;
const bodyElement = document.body;
if (htmlElement && bodyElement) {
Expand Down
Loading

0 comments on commit 3009087

Please sign in to comment.