Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Frontend] Add Q&A section in admin panel #901

Merged
merged 9 commits into from
May 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion backend/app/routes/Q&A/answers/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const updateAnswerStatus = require('./updateAnswerStatus');
router.post('/', validation(answerValidationSchema), postAnswer);

// GET API FOR ANSWERS
router.get('/:questionId', validation(getAnswerValidationSchema), getAnswers);
router.get('/:questionId', getAnswers);
Kajol-Kumari marked this conversation as resolved.
Show resolved Hide resolved

// INCREASE UPVOTE FOR ANSWERS
router.patch('/upvote', upvoteAnswer);
Expand Down
11 changes: 9 additions & 2 deletions frontend/src/pages/Admin/Admin.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,17 @@ import axios from "axios";
import { END_POINT } from "../../config/api";
import { useDispatch } from "react-redux";
import { ManageFaq } from "./Components/Faq/ManageFaq";
import { QandA } from "./Components/Faq/Q&A/QandA";
import { Manageqa } from "./Components/Faq/Q&A/ManageQ&A/ManageQ&A";

export const Admin = (props) => {
const [tab, setTab] = useState(1);
const [isMenuOpen, setIsMenuOpen] = useState(false);
const toggleNav = () => setIsMenuOpen(!isMenuOpen);
const closeMobileMenu = () => setIsMenuOpen(false);
const dispatch = useDispatch();
const firstName = localStorage.getItem("firstName");
const [qId,setQId] = useState("")
const [adminData, setAdminData] = useState({});
const FetchAdminData = async () => {
try {
Expand All @@ -50,7 +54,6 @@ export const Admin = (props) => {
console.error("There was a problem with the fetch operation:", error);
}
};

useEffect(() => {
const token = localStorage.getItem("token");
try {
Expand Down Expand Up @@ -174,7 +177,7 @@ export const Admin = (props) => {
className="fas fa-question fa-fw fa-lg"
aria-hidden="true"
></i>
<div className={style["span"]}>FAQs</div>
<div className={style["span"]}>FAQs and Q&As</div>
</div>
</li>
<li onClick={closeMobileMenu}>
Expand Down Expand Up @@ -244,6 +247,10 @@ export const Admin = (props) => {
<ResetPassword />
) : tab === 16 ? (
<ManageBroadcasts />
) : tab === 18 ? (
<QandA setQId={setQId} setTab={setTab} tab={tab} />
) : tab === 19 ? (
<Manageqa qId={qId} setTab={setTab} />
) : null}
</div>
</div>
Expand Down
15 changes: 14 additions & 1 deletion frontend/src/pages/Admin/Components/Faq/Faq.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Link } from "react-router-dom";
export function Faq(props) {
return (
<div className={style["faq"]}>
<h1 style={{ textAlign: "center" }}> FAQS </h1>
<h1 style={{ textAlign: "center" }}> FAQs and Q&As </h1>
<div className={style["cards"]}>
<div className={style["card-item"]}>
<div className={style["clickable-card"]}>
Expand Down Expand Up @@ -40,6 +40,19 @@ export function Faq(props) {
</div>
</div>
</div>
<div className={style["card-item"]}>
Hemu21 marked this conversation as resolved.
Show resolved Hide resolved
<div className={style["clickable-card"]}>
<div className={style["card-title"]}>
MANAGE Q&A
<AiFillEdit className={style["editt"]} />
</div>
<div className={style["card-content"]}>
<div onClick={()=>props.setTab(18)} className={style["main-btn"]}>
Manage here
</div>
</div>
</div>
</div>
</div>
</div>
);
Expand Down
213 changes: 213 additions & 0 deletions frontend/src/pages/Admin/Components/Faq/Q&A/ManageQ&A/ManageQ&A.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,213 @@
import { useEffect, useState } from "react";
import { END_POINT } from "../../../../../../config/api";
import style from "./manage.module.scss";
import { AiOutlineArrowLeft } from "react-icons/ai";
import { SimpleToast } from "../../../../../../components/util/Toast/Toast";
import Loader from "../../../../../../components/util/Loader";

export function Manageqa({ setTab, qId }) {
const [ans, setAns] = useState([]);
const [qns, setQns] = useState();
const [toogle, setToogle] = useState(false);
const [isLoaded, setIsLoaded] = useState(false);
const [toast, setToast] = useState({
toastStatus: false,
toastType: "",
toastMessage: "",
});
const getQuestion = async (id) => {
setIsLoaded(true);
try {
const qUrl = `${END_POINT}/question/getQuestionById/${id}`;
const qResponse = await fetch(qUrl);
const qRes = await qResponse.json();
setQns(qRes);
setToast({
...toast,
toastMessage: "Successfully get Question",
toastStatus: true,
toastType: "success",
});
} catch (error) {
console.log(error);
setIsLoaded(false);
setToast({
...toast,
toastMessage: "Check network failed to fetch",
toastStatus: true,
toastType: "error",
});
}
};
const updateQuestion = async (id, status) => {
try {
const qUrl = `${END_POINT}/question/updateStatus`;
const qResponse = await fetch(qUrl, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
body: JSON.stringify({ id: id, status: status }),
});
const qRes = await qResponse.json();
setToogle(!toogle);
setToast({
...toast,
toastMessage: "Updated Successfully!",
toastStatus: true,
toastType: "success",
});
} catch (error) {
console.log(error);
setToast({
...toast,
toastMessage: "Check network failed to update",
toastStatus: true,
toastType: "error",
});
}
};
const getAnswer = async (questionId) => {
try {
const aUrl = `${END_POINT}/answers/${questionId}`;
const aResponse = await fetch(aUrl);
const aRes = await aResponse.json();
setAns(aRes.data);
setIsLoaded(false);
setToast({
...toast,
toastMessage: "Successfully get answers",
toastStatus: true,
toastType: "success",
});
} catch (error) {
console.log(error);
setIsLoaded(false);
setToast({
...toast,
toastMessage: "Check network failed to fetch",
toastStatus: true,
toastType: "error",
});
}
};
const updateAnswer = async (id, status) => {
try {
const aUrl = `${END_POINT}/answers/updateStatus`;
const aResponse = await fetch(aUrl, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${localStorage.getItem("token")}`,
},
body: JSON.stringify({ id: id, status: status }),
});
const aRes = await aResponse.json();
setToogle(!toogle);
setToast({
...toast,
toastMessage: "Updated successfully",
toastStatus: true,
toastType: "success",
});
} catch (error) {
console.log(error);
setToast({
...toast,
toastMessage: "Check network failed to Update",
toastStatus: true,
toastType: "error",
});
}
};
const handleCloseToast = (event, reason) => {
if (reason === "clickaway") {
return;
}
setToast({ ...toast, toastStatus: false });
};
useEffect(() => {
getQuestion(qId);
getAnswer(qId);
}, [toogle]);
return (
<div>
<h1 className={style["head"]}>Manage Q&A</h1>
<div className={style["back"]}>
<AiOutlineArrowLeft size={"35px"} onClick={() => setTab(18)} />
</div>
<div className={style["data-loader"]}>{isLoaded ? <Loader /> : null}</div>
{isLoaded || (
<div className={style["card-item"]}>
<div className={style["card-info"]}>
<h1>{qns?.title}</h1>
<h2>Question</h2>
<div className={style["questionBox"]}>
<h3 className={style["card-question"]}>{qns?.description}</h3>
<div className={style["button-group"]}>
<button
className={
qns?.isApproved
? style["button-delete"]
: style["button-approve"]
}
id={`${qns?._id}`}
onClick={(e) => {
updateQuestion(e.currentTarget.id, !qns?.isApproved);
}}
>
{qns?.isApproved ? "DisApprove" : "Approve"}
</button>
<button className={style["button-delete"]}>Delete</button>
</div>
</div>

{ans?.length !== 0 ? (
<span>No answers Found</span>
) : (
ans?.map((a) => (
<>
<h2>Answers</h2>
<div className={style["answerBox"]}>
<h3 className={style["card-answer"]}>{a.answer}</h3>
<div className={style["button-group"]}>
<button
className={
a?.isApproved
? style["button-delete"]
: style["button-approve"]
}
id={`${a._id}`}
onClick={(e) => {
updateAnswer(e.currentTarget.id, !a?.isApproved);
}}
>
{a?.isApproved ? "DisApprove" : "Approve"}
</button>
<button className={style["button-delete"]}>Delete</button>
</div>
</div>
</>
))
)}

<div style={{ display: "flex", padding: "10px 30px 10px 30px" }}>
{qns?.tags?.map((tag) => (
<p className={style["tags"]}>{tag}</p>
))}
</div>
</div>
</div>
)}
{toast.toastStatus && (
<SimpleToast
open={toast.toastStatus}
message={toast.toastMessage}
handleCloseToast={handleCloseToast}
severity={toast.toastType}
/>
)}
</div>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./ManageQ&A";
Loading
Loading