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

updateFaq functionality and Integrate it with Backend #983

Merged
merged 2 commits into from
May 31, 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
167 changes: 154 additions & 13 deletions frontend/src/pages/Admin/Components/Faq/ManageFaq/ManageFaq.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import React from "react";
import { useEffect, useState } from "react";
import React, { useEffect, useState, useCallback } from "react";
import Accordion from "@material-ui/core/Accordion";
import AccordionDetails from "@material-ui/core/AccordionDetails";
import AccordionSummary from "@material-ui/core/AccordionSummary";
Expand All @@ -11,6 +10,7 @@ import { END_POINT } from "../../../../../config/api";
import Loader from "../../../../../components/util/Loader";
import style from "./manage-faq.module.scss";
import { SimpleToast } from "../../../../../components/util/Toast";
import { Button2 } from "../../../../../components/util/Button/index";

export function ManageFaq() {
const [faqs, setFaqs] = useState([]);
Expand All @@ -19,34 +19,38 @@ export function ManageFaq() {
const [open, setOpenToast] = useState(false);
const [toastMessage, setToastMessage] = useState("");
const [severity, setSeverity] = useState("success");
const [reload, setReload] = useState(true);
const handleCloseToast = () => {
const [reload, setReload] = useState(false);
const [faqObject, setFaqObject] = useState({});
const [openEditDialog, setOpenEditDialog] = useState(false);
const [formErrors, setFormErrors] = useState({});

const handleCloseToast = useCallback(() => {
setTimeout(() => {
setOpenToast(false);
}, 500);
};
}, []);

const handleChange = (panel) => (event, isExpanded) => {
setExpanded(isExpanded ? panel : false);
};
async function fetchAllFaq() {

const fetchAllFaq = useCallback(async () => {
setIsFetching(true);
try {
const response = await fetch(`${END_POINT}/faq/getFaq`);
const data = await response.json();
console.log(data);
setFaqs(data.Faq);
setIsFetching(false);
} catch (err) {
console.log(err.message);
setIsFetching(false);
}
}
}, []);

const deleteFaq = async (faqId) => {
setIsFetching(true);
const url = `${END_POINT}/faq/deleteFaq`;
const body = {
faqId: faqId,
};
const body = { faqId: faqId };
const headers = {
"Content-Type": "application/json",
authorization: `Bearer ${localStorage.getItem("token")}`,
Expand All @@ -73,9 +77,70 @@ export function ManageFaq() {
setIsFetching(false);
}
};

const updateFaq = async (faqId, updatedFaqDetails) => {
try {
const response = await fetch(`${END_POINT}/faq/updateFaq`, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
authorization: `Bearer ${localStorage.getItem("token")}`,
},
body: JSON.stringify({ faqId, ...updatedFaqDetails }),
});

if (!response.ok) {
throw new Error("Failed to update FAQ");
}

const data = await response.json();
setToastMessage(data.message);
setOpenToast(true);
setSeverity("success");
setReload((prev) => !prev);
} catch (error) {
console.error("Failed to update FAQ:", error.message);
setToastMessage("Failed to update FAQ");
setOpenToast(true);
setSeverity("error");
}
};

const handleEdit = (faqId) => {
const editedFaq = faqs.find((faq) => faq._id === faqId);
setFaqObject(editedFaq);
setOpenEditDialog(true);
};

const handleSaveEdit = () => {
if (validateForm()) {
updateFaq(faqObject._id, faqObject);
setOpenEditDialog(false);
}
};

const handleCancelEdit = () => {
setOpenEditDialog(false);
};

const validateForm = () => {
const errors = {};
if (!faqObject.question) {
errors.question = "* Question is required";
}
if (!faqObject.answer) {
errors.answer = "* Answer is required";
}
if (!faqObject.tags.length || faqObject.tags[0] === "") {
errors.tags = "* At least one tag is required";
}
setFormErrors(errors);
return Object.keys(errors).length === 0;
};

useEffect(() => {
fetchAllFaq();
}, [reload]);
}, [fetchAllFaq, reload]);

return (
<div>
Expand Down Expand Up @@ -129,8 +194,9 @@ export function ManageFaq() {
className={style["btns"]}
variant="contained"
endIcon={<Edit />}
onClick={() => handleEdit(faq._id)}
>
UPDATE
EDIT
</Button>
<Button
id={style["delete-btn"]}
Expand All @@ -148,6 +214,81 @@ export function ManageFaq() {
)}
</div>
</div>
{faqObject && openEditDialog && (
<div className={style["blur-background"]}>
<div className={style["edit-dialog"]}>
<h2 className={style["edit-dialog-heading"]}>Edit FAQ</h2>
<div className={style["edit-form"]}>
<label htmlFor="editedQuestion">Question:</label>
<input
id="editedQuestion"
type="text"
value={faqObject.question}
onChange={(e) =>
setFaqObject({ ...faqObject, question: e.target.value })
}
className={style["faq-input"]}
/>
{formErrors.question && (
<span className={style["error"]}>{formErrors.question}</span>
)}
<label htmlFor="editedAnswer">Answer:</label>
<input
id="editedAnswer"
type="text"
value={faqObject.answer}
onChange={(e) =>
setFaqObject({ ...faqObject, answer: e.target.value })
}
className={style["faq-input"]}
/>
{formErrors.answer && (
<span className={style["error"]}>{formErrors.answer}</span>
)}
<label htmlFor="editedIsActive">Is Active:</label>
<input
id="editedIsActive"
type="checkbox"
checked={faqObject.isActive}
onChange={(e) =>
setFaqObject({ ...faqObject, isActive: e.target.checked })
}
className={style["checkbox"]}
/>
<label htmlFor="editedTags">Tags:</label>
<input
id="editedTags"
type="text"
value={faqObject.tags.join(",")}
onChange={(e) =>
setFaqObject({
...faqObject,
tags: e.target.value.split(",").map(tag => tag.trim()),
})
}
className={style["faq-input"]}
/>
{formErrors.tags && (
<span className={style["error"]}>{formErrors.tags}</span>
)}
<div className={style["submit-btn"]}>
<Button2
className={style["submit-btn-text"]}
label="Save"
type="submit"
onClick={handleSaveEdit}
/>
<Button2
className={style["submit-btn-text"]}
label="Cancel"
type="button"
onClick={handleCancelEdit}
/>
</div>
</div>
</div>
</div>
)}
<SimpleToast
open={open}
message={toastMessage}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,18 @@
height: 37rem;
align-items: center;
}

.faq-input {
border-color: #1863ff;
outline: none;
border: double 1px transparent;
border-radius: 10px;
background-image: linear-gradient(white, white),
linear-gradient(to right, rgba(255, 0, 90, 1), rgba(10, 24, 61, 1));
background-origin: border-box;
background-clip: padding-box, border-box;
background-color: #ffffff;
}

.faq-container {
padding-bottom: 10px;
Expand Down Expand Up @@ -60,7 +72,6 @@
margin-top: 20px;
}
.btns {
color: white;
font-weight: bolder;
}
#delete-btn {
Expand All @@ -73,4 +84,113 @@
.accord-details {
display: flex;
flex-direction: column;
}
}
.edit-dialog {
position: fixed;
top: 30%;
left: 50%;
transform: translate(-50%, -50%);
padding-bottom: 30px;
border-radius: 15px;
z-index: 10013;
width: 60%;
height: auto;
background-color: #e7e7e7;
margin-top: 10%;
margin-left: auto;
margin-right: auto;
}
.blur-background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
backdrop-filter: blur(5px);
z-index: 1000;
}

.edit-dialog-heading {
text-align: center;
padding-top: 20px;
}

.edit-form {
width: 85%;
margin: 0 auto;
}

.edit-form label {
display: block;
margin-bottom: 5px;
color: #000;
}

.edit-form input[type="text"],
.edit-form textarea {
width: 100%;
height: 50px;
border: 1px solid #bbbaba;
border-radius: 10px;
padding: 0 25px;
color: #777777;
margin-bottom: 10px;
background-color: #f1f1f1;
box-shadow: inset 2px 2px 5px #888888, inset -2px -2px 5px #ffffff;
}

.edit-form textarea {
height: 180px;
resize: none;
}

.edit-actions {
display: flex;
justify-content: space-between;
margin-top: 20px;
}

.submit-btn {
display: flex;
justify-content: center;
width: 40%;
margin: 0 auto;
}

.submit-btn-text {
display: flex;
justify-content: center;
align-items: center;
}

.error {
color: rgb(219, 0, 0);
margin-top: 0;
padding-top: 0;
padding-bottom: 5px;
margin-bottom: 5px;
}

.checkbox {
cursor: pointer;
margin-bottom: 10px;
}


@media screen and (max-width: 750px) {
.edit-dialog {
width: 95%;
margin: 20% auto;
}

.edit-form input,
.edit-form textarea {
height: 40px;
}

.edit-actions button {
font-size: 14px;
}
}

Loading