From b0bde770823ff691684f876a9de2763e5f64dad3 Mon Sep 17 00:00:00 2001
From: karimalden
Date: Thu, 27 Jun 2024 12:47:33 +0300
Subject: [PATCH] QUESTION
---
src/Components/ValidationField/View/File.tsx | 3 ++
src/Hooks/useSaveOnDisconnect.tsx | 33 +++++++++++++++++++
src/Layout/Dashboard/FormikFormModel.tsx | 1 +
src/Pages/question/AddPage.tsx | 32 ++++++++++++++++--
src/Pages/question/EditPage.tsx | 29 +++++++++-------
src/Pages/question/Model/AcceptModal.tsx | 5 +++
src/Pages/question/Model/Add.tsx | 7 ++--
src/Pages/question/Model/Edit.tsx | 2 +-
.../question/Model/Field/ChoiceFields.tsx | 19 +++++++++--
src/Pages/question/Model/Field/File.tsx | 3 +-
src/Pages/question/Model/Malty/Add.tsx | 10 ++++--
.../Model/Malty/ChoiceField/ChoiceFields.tsx | 26 +++++++++++++--
src/Pages/question/Model/Malty/Edit.tsx | 7 ++--
.../Malty/QuestionFIeld/QuestionFIeld.tsx | 28 ++++++++++++++--
src/Pages/question/useTableColumns.tsx | 8 ++++-
src/Styles/Pages/exercise.scss | 7 ++++
src/api/config.ts | 4 +--
src/config/AppKey.ts | 1 +
src/translate/ar.json | 6 ++--
src/types/Item.ts | 1 +
src/utils/cleanObject.ts | 21 ++++++++++++
src/utils/hasItems.ts | 4 +++
src/zustand/ObjectToEditState.ts | 9 +++++
23 files changed, 232 insertions(+), 34 deletions(-)
create mode 100644 src/Hooks/useSaveOnDisconnect.tsx
create mode 100644 src/utils/cleanObject.ts
create mode 100644 src/utils/hasItems.ts
diff --git a/src/Components/ValidationField/View/File.tsx b/src/Components/ValidationField/View/File.tsx
index d0bbd2b..9e9758c 100644
--- a/src/Components/ValidationField/View/File.tsx
+++ b/src/Components/ValidationField/View/File.tsx
@@ -14,6 +14,9 @@ const File = ({
}: any) => {
const { formik, t, isError,errorMsg } = useFormField(name, props);
let imageUrl = formik?.values?.[name] ?? null;
+ console.log(imageUrl);
+ console.log(typeof imageUrl === 'string');
+
const fileList: UploadFile[] = useMemo(() => {
if (!imageUrl) return [];
diff --git a/src/Hooks/useSaveOnDisconnect.tsx b/src/Hooks/useSaveOnDisconnect.tsx
new file mode 100644
index 0000000..da2ae6c
--- /dev/null
+++ b/src/Hooks/useSaveOnDisconnect.tsx
@@ -0,0 +1,33 @@
+import { useEffect } from 'react';
+
+const useSaveOnDisconnect = (noChange: boolean, QUESTION_OBJECT_KEY: string, SavedQuestionData: any) => {
+ useEffect(() => {
+ const handleBeforeUnload = (event: BeforeUnloadEvent) => {
+ console.log("disconnect");
+ if (noChange) {
+ const jsonData = JSON.stringify(SavedQuestionData);
+ localStorage.setItem(QUESTION_OBJECT_KEY, jsonData);
+ }
+ };
+
+ const handleOffline = () => {
+ console.log("disconnect");
+ if (noChange) {
+ const jsonData = JSON.stringify(SavedQuestionData);
+ localStorage.setItem(QUESTION_OBJECT_KEY, jsonData);
+ }
+ };
+
+ // Add event listeners
+ window.addEventListener('beforeunload', handleBeforeUnload);
+ window.addEventListener('offline', handleOffline);
+
+ // Cleanup function
+ return () => {
+ window.removeEventListener('beforeunload', handleBeforeUnload);
+ window.removeEventListener('offline', handleOffline);
+ };
+ }, [noChange, QUESTION_OBJECT_KEY, SavedQuestionData]); // Add dependencies to the hook
+};
+
+export default useSaveOnDisconnect;
diff --git a/src/Layout/Dashboard/FormikFormModel.tsx b/src/Layout/Dashboard/FormikFormModel.tsx
index 091a230..abe35f0 100644
--- a/src/Layout/Dashboard/FormikFormModel.tsx
+++ b/src/Layout/Dashboard/FormikFormModel.tsx
@@ -42,6 +42,7 @@ const FormikFormModel: React.FC = ({
formik.resetForm();
}
}, [isOpen]);
+
return ;
}}
diff --git a/src/Pages/question/AddPage.tsx b/src/Pages/question/AddPage.tsx
index a8e4be4..819c8f5 100644
--- a/src/Pages/question/AddPage.tsx
+++ b/src/Pages/question/AddPage.tsx
@@ -17,12 +17,17 @@ import { toast } from "react-toastify";
import AcceptModal from "./Model/AcceptModal";
import { useModalState } from "../../zustand/Modal";
import { ModalEnum } from "../../enums/Model";
+import { cleanObject } from "../../utils/cleanObject";
+import { hasItems } from "../../utils/hasItems";
+import { QUESTION_OBJECT_KEY } from "../../config/AppKey";
+import useSaveOnDisconnect from "../../Hooks/useSaveOnDisconnect";
+import { getLocalStorage } from "../../utils/LocalStorage";
const AddPage: React.FC = () => {
const { mutate, isSuccess, isLoading ,mutateAsync} = useAddQuestion();
- const {object_to_edit,set_Tags_search,set_object_to_edit,set_Success} = useObjectToEdit()
+ const {object_to_edit,set_Tags_search,set_object_to_edit,set_Success,SavedQuestionData} = useObjectToEdit()
const {subject_id} = useParams()
const {isBseQuestion,set_isBseQuestion} = useObjectToEdit()
@@ -43,6 +48,8 @@ const AddPage: React.FC = () => {
"isBase": 1,
};
+
+
mutateAsync(newBseQuestion).then((data) => {
const newBseQuestionId = (data as any)?.data?.id;
const Questions = DataToSend?.Questions;
@@ -72,17 +79,36 @@ const AddPage: React.FC = () => {
if(isSuccess){
toast.success(t("validation.the_possess_done_successful"))
set_object_to_edit(null)
- set_Success(true)
+ set_Success(true)
+ localStorage.removeItem(QUESTION_OBJECT_KEY)
}
}, [isSuccess])
+ let cleanedQuestionOptions = cleanObject(SavedQuestionData);
+ let noChange =hasItems(cleanedQuestionOptions)
+
+ useSaveOnDisconnect(noChange, QUESTION_OBJECT_KEY, SavedQuestionData);
+
+
+ const SavedData = {} as any
+ console.log(SavedData);
const handleCancel = () => {
- setIsOpen(ModalEnum?.QUESTION_ACCEPT);
+ if(!noChange){
+ navigate(-1)
+ localStorage.removeItem(QUESTION_OBJECT_KEY)
+
+ }else{
+
+ setIsOpen(ModalEnum?.QUESTION_ACCEPT);
+ }
};
const [t] = useTranslation();
+
+
+
if(isBseQuestion){
return (
diff --git a/src/Pages/question/EditPage.tsx b/src/Pages/question/EditPage.tsx
index 321e05f..c9d5b90 100644
--- a/src/Pages/question/EditPage.tsx
+++ b/src/Pages/question/EditPage.tsx
@@ -2,7 +2,7 @@ import React, { useEffect } from "react";
import { Modal, Spin } from "antd";
import FormikForm from "../../Layout/Dashboard/FormikFormModel";
import { getInitialValues, getValidationSchema ,getInitialValuesBase, getValidationSchemaBase, processTags} from "./Model/formUtil";
-import { useAddQuestion, useGetAllQuestion, useUpdateQuestion } from "../../api/Question";
+import { useAddQuestion, useDeleteQuestion, useGetAllQuestion, useUpdateQuestion } from "../../api/Question";
import { useQueryClient } from "react-query";
import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom";
@@ -19,17 +19,17 @@ import { toast } from "react-toastify";
const EditPage: React.FC = () => {
const {question_id,subject_id} = useParams
()
- const {isBseQuestion,set_isBseQuestion,set_Tags_search} = useObjectToEdit()
+ const {isBseQuestion,set_isBseQuestion,set_Tags_search,DeletedQuestions} = useObjectToEdit()
const { mutate, isSuccess, isLoading } = useUpdateQuestion();
- const { mutate:AddQuestion} = useAddQuestion();
+ const { mutate:DeleteQuestion} = useDeleteQuestion();
const {data,isLoading:dataLoading}= useGetAllQuestion({show:question_id})
const {data:Questions,isLoading:QuestionsDataLoading}= useGetAllQuestion({questionParentId:question_id})
const object_to_edit = {...data?.data,Questions:Questions?.data } ;
-
+
useEffect(() => {
if(object_to_edit?.isBase === 1 && isBseQuestion !== true){
@@ -45,7 +45,6 @@ const EditPage: React.FC = () => {
console.log(DataToSend);
if(isBseQuestion){
- console.log(1);
const UpdateBseQuestion = {
"id":DataToSend?.id,
@@ -55,11 +54,18 @@ const EditPage: React.FC = () => {
if( typeof UpdateBseQuestion?.image === "string"){
delete UpdateBseQuestion["image"]
}
- console.log(UpdateBseQuestion);
-
- mutate(UpdateBseQuestion)
+ console.log(DeletedQuestions,"DeletedQuestions");
+
+ mutate(UpdateBseQuestion)
- const Questions = DataToSend?.Questions;
+
+ DeletedQuestions?.map((item:any)=>{
+ DeleteQuestion({id:item?.id})
+
+ })
+
+
+ const Questions = DataToSend?.Questions;
console.log(Questions,"Questions");
Questions?.map((item:Question)=>{
@@ -84,8 +90,9 @@ const EditPage: React.FC = () => {
const QuestionOptions = {
old: oldQuestionOptions,
new: newQuestionOptions
- };
-
+ } ;
+ console.log(QuestionOptions);
+
mutate({
...updatedObject,
QuestionOptions,
diff --git a/src/Pages/question/Model/AcceptModal.tsx b/src/Pages/question/Model/AcceptModal.tsx
index 37a7828..0e2b8b3 100644
--- a/src/Pages/question/Model/AcceptModal.tsx
+++ b/src/Pages/question/Model/AcceptModal.tsx
@@ -5,6 +5,7 @@ import { ModalEnum } from "../../../enums/Model";
import { useTranslation } from "react-i18next";
import { useNavigate } from "react-router-dom";
import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
+import { QUESTION_OBJECT_KEY } from "../../../config/AppKey";
const AcceptModal: React.FC = () => {
const { isOpen, setIsOpen } = useModalState((state) => state);
@@ -12,8 +13,12 @@ const AcceptModal: React.FC = () => {
const handleSubmit = () => {
+ localStorage.removeItem(QUESTION_OBJECT_KEY)
console.log("Handle submit clicked");
+ setIsOpen("");
+
navigate(-1)
+
};
const handleCancel = () => {
diff --git a/src/Pages/question/Model/Add.tsx b/src/Pages/question/Model/Add.tsx
index a977876..676516e 100644
--- a/src/Pages/question/Model/Add.tsx
+++ b/src/Pages/question/Model/Add.tsx
@@ -15,7 +15,7 @@ import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
const Form = () => {
const formik = useFormikContext();
- const{set_Success,Success} = useObjectToEdit()
+ const{set_Success,Success,set_SavedQuestionData} = useObjectToEdit()
useEffect(() => {
if (Success) {
@@ -25,6 +25,9 @@ const Form = () => {
}
}, [Success]);
+useEffect(() => {
+ set_SavedQuestionData(formik.values)
+}, [formik?.values])
@@ -79,7 +82,7 @@ const Form = () => {
}
)
}
- {formik?.values?.QuestionOptions?.length < 4 && (
+ {formik?.values?.QuestionOptions?.length < 5 && (
{t("header.add_new_choice")}
diff --git a/src/Pages/question/Model/Edit.tsx b/src/Pages/question/Model/Edit.tsx
index 565a5dc..3d93407 100644
--- a/src/Pages/question/Model/Edit.tsx
+++ b/src/Pages/question/Model/Edit.tsx
@@ -65,7 +65,7 @@ const Form = () => {
}
)
}
- {formik?.values?.QuestionOptions?.length < 4 && (
+ {formik?.values?.QuestionOptions?.length < 5 && (
{t("header.add_new_choice")}
diff --git a/src/Pages/question/Model/Field/ChoiceFields.tsx b/src/Pages/question/Model/Field/ChoiceFields.tsx
index 864c0e3..84da61a 100644
--- a/src/Pages/question/Model/Field/ChoiceFields.tsx
+++ b/src/Pages/question/Model/Field/ChoiceFields.tsx
@@ -7,11 +7,24 @@ import { getCharFromNumber } from '../../../../utils/getCharFromNumber';
import CheckboxField from './CheckboxField';
import TextField from './TextField';
import File from './File';
+import { FaCirclePlus, FaDeleteLeft } from 'react-icons/fa6';
+import { FaTrash } from 'react-icons/fa';
const ChoiceFields = ({index,data}:{index:number , data :Choice }) => {
- const formik = useFormikContext();
+ const formik = useFormikContext();
const [t] = useTranslation()
+
+ const handleDeleteChoice = () => {
+ console.log(index);
+ console.log(formik.values.QuestionOptions[index]);
+
+ const updatedQuestionOptions = formik.values.QuestionOptions.filter((_:any, i:any) => i !== index);
+
+ formik.setFieldValue('QuestionOptions', updatedQuestionOptions);
+ };
+console.log(formik.values);
+
return (
@@ -20,7 +33,9 @@ const ChoiceFields = ({index,data}:{index:number , data :Choice }) => {
-
+
+
+
)
}
diff --git a/src/Pages/question/Model/Field/File.tsx b/src/Pages/question/Model/Field/File.tsx
index e02140f..e9e0dc6 100644
--- a/src/Pages/question/Model/Field/File.tsx
+++ b/src/Pages/question/Model/Field/File.tsx
@@ -18,7 +18,8 @@ const File = ({
const { formik, t, isError,errorMsg } = useFormField(newName, props);
let imageUrl = formik?.values?.QuestionOptions[name]?.answer_image ?? null;
// console.log(imageUrl);
-
+ console.log(imageUrl);
+
const fileList: UploadFile[] = useMemo(() => {
if (!imageUrl) return [];
diff --git a/src/Pages/question/Model/Malty/Add.tsx b/src/Pages/question/Model/Malty/Add.tsx
index dd1ab95..0079d89 100644
--- a/src/Pages/question/Model/Malty/Add.tsx
+++ b/src/Pages/question/Model/Malty/Add.tsx
@@ -107,9 +107,15 @@ const Form = () => {
}
)
}
-
+
+ {formik?.values?.Questions?.[parent_index]?.QuestionOptions?.length < 5 && (
+
handleAddChoice(parent_index)} size={23} /> {t("header.add_new_choice")}
-
+
+
+ )}
+
+
diff --git a/src/Pages/question/Model/Malty/ChoiceField/ChoiceFields.tsx b/src/Pages/question/Model/Malty/ChoiceField/ChoiceFields.tsx
index 426850e..3c5a9f6 100644
--- a/src/Pages/question/Model/Malty/ChoiceField/ChoiceFields.tsx
+++ b/src/Pages/question/Model/Malty/ChoiceField/ChoiceFields.tsx
@@ -7,11 +7,31 @@ import { getCharFromNumber } from '../../../../../utils/getCharFromNumber';
import CheckboxField from './CheckboxField';
import TextField from './TextField';
import File from './File';
+import { FaTrash } from 'react-icons/fa';
+import { toast } from 'react-toastify';
const ChoiceFields = ({index,parent_index,data}:{index:number ,parent_index:number, data :Choice }) => {
- const formik = useFormikContext();
+ const formik = useFormikContext();
const [t] = useTranslation()
+
+ const handleDeleteChoice = () => {
+ const arrayLength = formik.values.Questions?.[parent_index].QuestionOptions?.length
+
+ console.log(arrayLength);
+
+ if(arrayLength === 1)
+ {
+ toast.error(t("validation.Sorry, the question must have at least one option"))
+ return ;
+ }
+
+
+ const updatedQuestionOptions = formik.values.Questions?.[parent_index].QuestionOptions.filter((_:any, i:any) => i !== index);
+ formik.setFieldValue(`Questions[${parent_index}].QuestionOptions`, updatedQuestionOptions);
+ }
+ ;
+
return (
@@ -20,7 +40,9 @@ const ChoiceFields = ({index,parent_index,data}:{index:number ,parent_index:numb
-
+
+
+
)
}
diff --git a/src/Pages/question/Model/Malty/Edit.tsx b/src/Pages/question/Model/Malty/Edit.tsx
index dd26b22..12b27d7 100644
--- a/src/Pages/question/Model/Malty/Edit.tsx
+++ b/src/Pages/question/Model/Malty/Edit.tsx
@@ -101,9 +101,12 @@ const Form = () => {
}
)
}
-
+ {formik?.values?.Questions?.[parent_index]?.QuestionOptions?.length < 5 && (
+
handleAddChoice(parent_index)} size={23} /> {t("header.add_new_choice")}
-
+
+
+ )}
diff --git a/src/Pages/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx b/src/Pages/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx
index 47ec2f1..5298496 100644
--- a/src/Pages/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx
+++ b/src/Pages/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx
@@ -1,4 +1,4 @@
-import React from 'react'
+import React, { useEffect } from 'react'
import { Choice } from '../../../../../types/Item'
import ValidationField from '../../../../../Components/ValidationField/ValidationField'
import { useFormikContext } from 'formik';
@@ -6,18 +6,40 @@ import { useTranslation } from 'react-i18next';
import { getCharFromNumber } from '../../../../../utils/getCharFromNumber';
import TextField from './TextField';
import File from './File';
+import { FaTrash } from 'react-icons/fa';
+import { useObjectToEdit } from '../../../../../zustand/ObjectToEditState';
+import { toast } from 'react-toastify';
const QuestionFIeld = ({index,data}:{index:number , data :Choice }) => {
- const formik = useFormikContext();
+ const formik = useFormikContext();
console.log(index);
+ const {set_DeletedQuestions,DeletedQuestions} = useObjectToEdit()
const [t] = useTranslation()
+ useEffect(() => {
+ set_DeletedQuestions([])
+ }, [window?.location.pathname])
+
+ const handleDeleteQuestion = () => {
+
+ const DeleteQuestionId = formik.values.Questions?.[index];
+ if(DeleteQuestionId?.id){
+ set_DeletedQuestions([...DeletedQuestions,DeleteQuestionId])
+
+ }
+ const updatedQuestionOptions = formik.values.Questions.filter((_:any, i:any) => i !== index);
+ formik.setFieldValue(`Questions`, updatedQuestionOptions);
+ };
+
+
return (
)
}
diff --git a/src/Pages/question/useTableColumns.tsx b/src/Pages/question/useTableColumns.tsx
index 08ad6f4..1fc6158 100644
--- a/src/Pages/question/useTableColumns.tsx
+++ b/src/Pages/question/useTableColumns.tsx
@@ -79,7 +79,13 @@ export const useColumns = () => {
align: "center",
render: (text, record) => record?.isBase === 1 ? t("practical.yes") : t ("practical.no"),
},
-
+ {
+ title: `${t("columns.question_options_count")}`,
+ dataIndex: "name",
+ key: "name",
+ align: "center",
+ render: (text, record) => record?.question_options_count,
+ },
{
title: can_add_Question ? (