Skip to content

Commit

Permalink
⬆️updateFaq functionality and Integrate it with Backend (#983)
Browse files Browse the repository at this point in the history
* adding updateFaq functionality

* fix updateFaq
  • Loading branch information
shivamgaur99 authored May 31, 2024
1 parent 5647fcd commit 5dbac86
Show file tree
Hide file tree
Showing 2 changed files with 276 additions and 15 deletions.
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;
}
}

0 comments on commit 5dbac86

Please sign in to comment.