add check on reload

This commit is contained in:
karimaldeen 2024-09-22 11:09:15 +03:00
parent ec4850cbb8
commit 470cae3b13
21 changed files with 770 additions and 493 deletions

View File

@ -1,5 +1,4 @@
import TextArea from 'antd/es/input/TextArea'; import TextArea from 'antd/es/input/TextArea';
import { useFormikContext } from 'formik';
import React, { Suspense, useEffect, useState } from 'react'; import React, { Suspense, useEffect, useState } from 'react';
import { parseTextAndLatex } from '../../utils/parseTextAndLatex'; import { parseTextAndLatex } from '../../utils/parseTextAndLatex';
import LatexPreview from '../CustomFields/MathComponent'; import LatexPreview from '../CustomFields/MathComponent';
@ -49,15 +48,24 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
setCurrentValue(e.target.value) setCurrentValue(e.target.value)
}; };
const onBlur = ()=>{ const onBlur = ()=>{
if (curCentValue !== value) {
setFieldValue(name, curCentValue); setFieldValue(name, curCentValue);
}
} }
useEffect(() => { useEffect(() => {
if(Success){ if(Success){
setCurrentValue(null) setCurrentValue(null)
} }
}, [Success]) }, [Success])
useEffect(() => {
if(value){
setCurrentValue(value)
}
}, [value])
const isError = !!touched?.[name] && !!errors?.[name]; const isError = !!touched?.[name] && !!errors?.[name];
const errorMessage = isError ? errors?.[name] as string ?? "" : "" ; const errorMessage = isError ? errors?.[name] as string ?? "" : "" ;
return ( return (
@ -93,7 +101,7 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
{Preview?.map((item: any, index: number) => { {Preview?.map((item: any, index: number) => {
if (item?.isLatex) { if (item?.isLatex) {
return ( return (
<div key={index} onClick={() => handleEditModal(item)} className='LatexPreview'> <div dir='ltr' key={index} onClick={() => handleEditModal(item)} className='LatexPreview'>
<LatexPreview Latex={item?.text} /> <LatexPreview Latex={item?.text} />
</div> </div>
); );
@ -104,9 +112,10 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
)} )}
</div> </div>
<AddLazyModal name={name} Latex={Latex} isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} setLatex={setLatex} setCurrentValue={setCurrentValue} /> <Suspense fallback={<SpinContainer />}>
<EditLazyModal name={name} Latex={Latex} isModalOpen={isEditModalOpen} setIsModalOpen={setIsEditModalOpen} setLatex={setLatex} /> <AddLazyModal name={name} Latex={Latex} isModalOpen={isModalOpen} setIsModalOpen={setIsModalOpen} setLatex={setLatex} setCurrentValue={setCurrentValue} />
<Suspense fallback={<SpinContainer />}> <EditLazyModal name={name} Latex={Latex} isModalOpen={isEditModalOpen} setIsModalOpen={setIsEditModalOpen} setLatex={setLatex} />
</Suspense> </Suspense>
</div> </div>
); );

View File

@ -0,0 +1,42 @@
import { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
const useUnsavedChangesWarning = (unsavedChanges: boolean) => {
const [t] = useTranslation();
useEffect(() => {
const handleBeforeUnload = (event: BeforeUnloadEvent) => {
if (unsavedChanges) {
// Prevent default action and stop the event
event.preventDefault();
// Optionally set returnValue to an empty string
event.returnValue = '';
}
};
const handleNavigation = (event: MouseEvent) => {
if (unsavedChanges) {
console.log(t("Access denied: You have unsaved changes!"));
event.preventDefault();
}
};
window.addEventListener('beforeunload', handleBeforeUnload);
// Intercept link clicks (example for <a> elements)
document.querySelectorAll('a').forEach(link => {
link.addEventListener('click', handleNavigation);
});
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload);
// Clean up event listeners
document.querySelectorAll('a').forEach(link => {
link.removeEventListener('click', handleNavigation);
});
};
}, [unsavedChanges, t]);
};
export default useUnsavedChangesWarning;

View File

@ -36,7 +36,6 @@ const DynamicTags = () => {
if (currentElement) { if (currentElement) {
currentElement.focus(); // Set focus on the element currentElement.focus(); // Set focus on the element
} }
console.log(currentElement,"currentElement");
}, [lastElementIndex]) }, [lastElementIndex])
// console.log(formik?.values); // console.log(formik?.values);

View File

@ -167,7 +167,6 @@ const DrapableTable: React.FC = () => {
const [t] = useTranslation(); const [t] = useTranslation();
const columns = useColumns(); const columns = useColumns();
const sortedDataSource = dataSource.sort((a, b) => a.order - b.order); const sortedDataSource = dataSource.sort((a, b) => a.order - b.order);
console.log(sortedDataSource, "sortedDataSource");
return ( return (
<DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}> <DndContext modifiers={[restrictToVerticalAxis]} onDragEnd={onDragEnd}>

View File

@ -1,38 +1,26 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { Spin } from "antd";
import { import {
getInitialValues,
getValidationSchema,
getInitialValuesBase,
getValidationSchemaBase,
processTags, processTags,
} from "./formUtil"; } from "./formUtil";
import { useAddQuestion, useAddQuestionAsync } from "../../../api/Question"; import { useAddQuestion, useAddQuestionAsync } from "../../../api/Question";
import { useTranslation } from "react-i18next"; import { useParams } from "react-router-dom";
import { useLocation, useNavigate, useParams } from "react-router-dom";
import { ParamsEnum } from "../../../enums/params"; import { ParamsEnum } from "../../../enums/params";
import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import Header from "../../../Components/exercise/Header";
import { Question } from "../../../types/Item"; import { Question } from "../../../types/Item";
import BaseForm from "./Model/Malty/Form"; import BaseFormContainer from "./Model/AddForm/BaseForm";
import ModelForm from "./Model/ModelForm"; import FormContainer from "./Model/AddForm/Form";
import { toast } from "react-toastify"; import { handleValidateBaseQuestion, handleValidateSingleQuestion } from "./Model/AddForm/ValidationFn";
import { Form, Formik } from "formik"; import useUnsavedChangesWarning from "../../../Hooks/useUnsavedChangesWarning";
import { MdOutlineArrowForwardIos } from "react-icons/md"; import { useFormikContext } from "formik";
const AddPage: React.FC = () => { const AddPage: React.FC = () => {
const location = useLocation();
const { mutateAsync,isLoading:LoadingAsync } = useAddQuestionAsync(); const { mutateAsync, isLoading: LoadingAsync } = useAddQuestionAsync();
const { mutate, isLoading, isSuccess } = useAddQuestion(); const { mutate, isLoading, isSuccess } = useAddQuestion();
const { isBseQuestion, setTagsSearch, setSuccess } = const { isBseQuestion, setTagsSearch, setSuccess } = useObjectToEdit();
useObjectToEdit();
const [t] = useTranslation();
const { subject_id, lesson_id } = useParams<ParamsEnum>(); const { subject_id, lesson_id } = useParams<ParamsEnum>();
const handleFormSubmit = ( values: any) => { const handleFormSubmit = (values: any) => {
const DataToSend = structuredClone(values); const DataToSend = structuredClone(values);
setTagsSearch(null); setTagsSearch(null);
@ -63,7 +51,7 @@ const AddPage: React.FC = () => {
...item, ...item,
}; };
}); });
mutate({ mutate({
...item, ...item,
parent_id: newBseQuestionId, parent_id: newBseQuestionId,
@ -99,216 +87,27 @@ const AddPage: React.FC = () => {
mutate(NewQuestion); mutate(NewQuestion);
} }
}; };
const handleValidateSingleQuestion = (values:any,isValid:boolean,handleSubmit:any)=>{
const haveMoreThanOneAnswer = values?.answers?.length > 1;
const haveOneAnswerRight = haveMoreThanOneAnswer && values?.answers?.some((item:any)=> item?.isCorrect === 1 || item.isCorrect === true )
const haveImageOrContent = haveOneAnswerRight && values?.answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
const content = values.content ;
const content_image = values.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
console.log(haveImageOrContent,"haveImageOrContent");
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
if(!haveMoreThanOneAnswer){
toast.error(t("validation.it_should_have_more_than_one_answers")) ;
return false ;
}
if(!haveOneAnswerRight){
toast.error(t("validation.it_should_have_more_than_one_correct_answers")) ;
return false ;
}
if(haveImageOrContent){
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer"))
return false
}
console.log(1);
if(isValid){
handleSubmit(values)
}
}
const handleValidateBaseQuestion = (values: any,isValid:boolean,handleSubmit:any) => {
const content = values.content ;
const content_image = values.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
console.log(2);
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
console.log(1);
const isValidate = values?.Questions?.every((Question: any, QuestionsIndex: number) => {
const content = Question.content ;
const content_image = Question.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
//// answers
const answers = Question?.answers;
const haveAnswers = answers?.length > 0;
const haveMoreThanOneAnswer = haveAnswers && answers?.length > 1;
const haveOneAnswerRight = haveMoreThanOneAnswer && answers?.some((item: any) => item?.isCorrect === 1 || item.isCorrect === true);
const haveImageOrContent = haveOneAnswerRight && answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
if (!haveAnswers) {
toast.error(t("validation.it_should_have_more_than_one_answers"));
return false;
}
if (!haveMoreThanOneAnswer) {
toast.error(t("validation.it_should_have_more_than_one_answers"));
return false;
}
if (!haveOneAnswerRight) {
toast.error(t("validation.it_should_have_more_than_one_correct_answers"));
return false;
}
if(haveImageOrContent){
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer"))
return false
}
return true
});
console.log(1);
if(isValid && isValidate){
console.log(2);
handleSubmit(values)
}
};
const navigate = useNavigate();
const handleNavigateToPage = () => {
const cleanedUrl = location.pathname?.replace("/Question/add", "");
navigate(cleanedUrl);
};
const handleCancel = () => {
navigate(-1);
};
const Loading = LoadingAsync || isLoading; const Loading = LoadingAsync || isLoading;
useEffect(() => { useEffect(() => {
if (isSuccess) { if (isSuccess) {
setSuccess(true); setSuccess(true);
} }
}, [isSuccess]); }, [isSuccess]);
if (isBseQuestion) { if (isBseQuestion) {
return ( return (
<div className="QuestionPractical">
<header>
<MdOutlineArrowForwardIos onClick={handleNavigateToPage} /> {t("header.add_new_question")}
</header>
<div className="exercise_add"> <BaseFormContainer Loading={Loading} handleFormSubmit={handleFormSubmit} handleValidateBaseQuestion={handleValidateBaseQuestion} />
<Formik
onSubmit={handleFormSubmit}
initialValues={getInitialValuesBase({} as any)}
validationSchema={getValidationSchemaBase}
enableReinitialize
>
{({ values,isValid,handleSubmit }) => (
<Form className="w-100">
<main className="w-100 exercise_add_main">
<Header />
<BaseForm />
<div className="exercise_add_buttons">
<div onClick={handleCancel}>{t("practical.back")}</div>
<button disabled={Loading} className="relative" type="button"
onClick={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit) }}
onSubmit={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit) }}
>
{t("practical.add")}
{Loading && (
<span className="Spinier_Div">
<Spin />
</span>
)}
</button>
</div>
</main>
</Form>
)}
</Formik>
</div>
</div>
); );
} }
return ( return (
<div className="QuestionPractical"> <FormContainer Loading={Loading} handleFormSubmit={handleFormSubmit} handleValidateSingleQuestion={handleValidateSingleQuestion} />
<header>
<MdOutlineArrowForwardIos onClick={handleNavigateToPage} /> {t("header.add_new_question")}
</header>
<div className="exercise_add">
<Formik
enableReinitialize={true}
initialValues={getInitialValues({} as any)}
validationSchema={getValidationSchema}
validateOnMount={true}
onSubmit={(values) => {
handleFormSubmit(values);
}}
>
{({ values,isValid ,handleSubmit}) => (
<Form className="w-100">
<main className="w-100 exercise_add_main">
<Header />
<ModelForm />
<div className="exercise_add_buttons">
<div onClick={handleCancel}>{t("practical.back")}</div>
<div
className="relative"
onClick={()=>{ Loading ? ()=>{} : handleValidateSingleQuestion(values,isValid,handleSubmit) }}
>
{t("practical.add")}
{Loading && (
<span className="Spinier_Div">
<Spin />
</span>
)}
</div>
</div>
</main>
</Form>
)}
</Formik>
</div>
</div>
); );
}; };

View File

@ -1,10 +1,5 @@
import React, { useEffect } from "react"; import React, { useEffect } from "react";
import { Checkbox, Modal, Popover, Spin } from "antd";
import { import {
getInitialValues,
getValidationSchema,
getInitialValuesBase,
getValidationSchemaBase,
processTags, processTags,
} from "./formUtil"; } from "./formUtil";
import { import {
@ -19,25 +14,20 @@ import { ParamsEnum } from "../../../enums/params";
import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import { removeStringKeys } from "../../../utils/removeStringKeys"; import { removeStringKeys } from "../../../utils/removeStringKeys";
import SpinContainer from "../../../Components/Layout/SpinContainer"; import SpinContainer from "../../../Components/Layout/SpinContainer";
import ModelForm from "./Model/ModelForm";
import BaseForm from "./Model/Malty/Form";
import { Question } from "../../../types/Item"; import { Question } from "../../../types/Item";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import { deletePathSegments } from "../../../utils/deletePathSegments"; import { deletePathSegments } from "../../../utils/deletePathSegments";
import { Form, Formik } from "formik"; import BaseFormContainer from "./Model/EditForm/BaseFormContainer";
import { MdOutlineArrowForwardIos } from "react-icons/md"; import FormContainer from "./Model/EditForm/FormContainer";
import { SettingFilled } from "@ant-design/icons";
import { CheckboxProps } from "antd/lib";
import { LocalStorageEnum } from "../../../enums/LocalStorageEnum";
const EditPage: React.FC = () => { const EditPage: React.FC = () => {
const { subject_id, lesson_id, question_id } = useParams<ParamsEnum>(); const { subject_id, lesson_id, question_id } = useParams<ParamsEnum>();
const { isBseQuestion, setIsBseQuestion, setTagsSearch, DeletedQuestions , ShowHint,setShowHint , ShowLatexOption,setShowLatexOption } = const { isBseQuestion, setIsBseQuestion, setTagsSearch, DeletedQuestions, ShowHint, setShowHint, ShowLatexOption, setShowLatexOption } =
useObjectToEdit(); useObjectToEdit();
const { mutate, isSuccess, isLoading } = useUpdateQuestion(); const { mutate, isSuccess, isLoading } = useUpdateQuestion();
const { mutate: DeleteQuestion } = useDeleteQuestion(); const { mutate: DeleteQuestion } = useDeleteQuestion();
const { mutate: mutateAdd , isLoading:LoadingAsync } = useAddQuestion(); const { mutate: mutateAdd, isLoading: LoadingAsync } = useAddQuestion();
const { data, isLoading: dataLoading } = useGetAllQuestion({ const { data, isLoading: dataLoading } = useGetAllQuestion({
show: question_id, show: question_id,
@ -46,7 +36,7 @@ const EditPage: React.FC = () => {
const { data: Questions, isLoading: QuestionsDataLoading } = const { data: Questions, isLoading: QuestionsDataLoading } =
useGetAllQuestion({ useGetAllQuestion({
parent_id: question_id, parent_id: question_id,
isPaginated:false isPaginated: false
}); });
const objectToEdit = { ...data?.data, Questions: Questions?.data }; const objectToEdit = { ...data?.data, Questions: Questions?.data };
@ -62,7 +52,7 @@ const EditPage: React.FC = () => {
const handleSubmit = (values: any) => { const handleSubmit = (values: any) => {
const DataToSend = structuredClone(values); const DataToSend = structuredClone(values);
setTagsSearch(null); setTagsSearch(null);
if (isBseQuestion) { if (isBseQuestion) {
const UpdateBseQuestion = { const UpdateBseQuestion = {
@ -79,7 +69,7 @@ const EditPage: React.FC = () => {
console.log(DeletedQuestions, "DeletedQuestions"); console.log(DeletedQuestions, "DeletedQuestions");
console.log(UpdateBseQuestion); console.log(UpdateBseQuestion);
// mutate(UpdateBseQuestion); mutate(UpdateBseQuestion);
DeletedQuestions?.map((item: any) => { DeletedQuestions?.map((item: any) => {
DeleteQuestion({ id: item?.id }); DeleteQuestion({ id: item?.id });
@ -93,8 +83,8 @@ const EditPage: React.FC = () => {
if (item?.id) { if (item?.id) {
const itemToSend = structuredClone(item); const itemToSend = structuredClone(item);
const keysToRemove = ["content_image"]; const keysToRemove = ["content_image"];
console.log(itemToSend,"itemToSend"); console.log(itemToSend, "itemToSend");
const updatedObject = removeStringKeys(itemToSend, keysToRemove); const updatedObject = removeStringKeys(itemToSend, keysToRemove);
console.log(updatedObject, "updatedObject"); console.log(updatedObject, "updatedObject");
@ -102,14 +92,14 @@ const EditPage: React.FC = () => {
const oldAnswers = [] as any; const oldAnswers = [] as any;
const newAnswers = [] as any; const newAnswers = [] as any;
if(updatedObject?.content_image === null){ if (updatedObject?.content_image === null) {
updatedObject["content_image"] = "" updatedObject["content_image"] = ""
} }
updatedObject?.answers?.forEach((item: any) => { updatedObject?.answers?.forEach((item: any) => {
if (item?.id) { if (item?.id) {
if(item?.content_image === null){ if (item?.content_image === null) {
item["content_image"] = "" item["content_image"] = ""
} }
oldAnswers.push({ ...item, isCorrect: item?.isCorrect ? 1 : 0 }); oldAnswers.push({ ...item, isCorrect: item?.isCorrect ? 1 : 0 });
@ -121,20 +111,20 @@ const EditPage: React.FC = () => {
old: oldAnswers, old: oldAnswers,
new: newAnswers, new: newAnswers,
}; };
const emptyTag = tags?.new?.length === 0 && tags?.old?.length === 0 const emptyTag = tags?.new?.length === 0 && tags?.old?.length === 0
const tagToSend = emptyTag ? "" : tags const tagToSend = emptyTag ? "" : tags
mutate({ mutate({
...updatedObject, ...updatedObject,
answers, answers,
tags:tagToSend, tags: tagToSend,
}); });
} else { } else {
console.log(values?.id); console.log(values?.id);
const tags = processTags(item); const tags = processTags(item);
console.log(item,"DataToSend"); console.log(item, "DataToSend");
console.log(tags,"tags"); console.log(tags, "tags");
mutateAdd({ mutateAdd({
...item, ...item,
subject_id: subject_id, subject_id: subject_id,
@ -158,15 +148,15 @@ const EditPage: React.FC = () => {
const newAnswers = [] as any; const newAnswers = [] as any;
updatedObject?.answers?.forEach((item: any) => { updatedObject?.answers?.forEach((item: any) => {
if (item?.id) { if (item?.id) {
console.log(item,"item"); console.log(item, "item");
const deletedImage = item?.content_image === null const deletedImage = item?.content_image === null
if(deletedImage){ if (deletedImage) {
oldAnswers.push({ ...item, isCorrect: item?.isCorrect ? 1 : 0, content_image:"" }); oldAnswers.push({ ...item, isCorrect: item?.isCorrect ? 1 : 0, content_image: "" });
}else{ } else {
oldAnswers.push({ ...item, isCorrect: item?.isCorrect ? 1 : 0 }); oldAnswers.push({ ...item, isCorrect: item?.isCorrect ? 1 : 0 });
} }
} else { } else {
newAnswers.push({ ...item, isCorrect: item?.isCorrect ? 1 : 0 }); newAnswers.push({ ...item, isCorrect: item?.isCorrect ? 1 : 0 });
} }
@ -187,113 +177,105 @@ const EditPage: React.FC = () => {
const location = useLocation(); const location = useLocation();
const navigate = useNavigate(); const navigate = useNavigate();
const handleCancel = () => {
navigate(-1);
};
const handleValidateSingleQuestion = (values:any,isValid:boolean,handleSubmit:any)=>{ const handleValidateSingleQuestion = (values: any, isValid: boolean, handleSubmit: any) => {
const haveMoreThanOneAnswer = values?.answers?.length > 1; const haveMoreThanOneAnswer = values?.answers?.length > 1;
const haveOneAnswerRight = haveMoreThanOneAnswer && values?.answers?.some((item:any)=> item?.isCorrect === 1 || item.isCorrect === true ) const haveOneAnswerRight = haveMoreThanOneAnswer && values?.answers?.some((item: any) => item?.isCorrect === 1 || item.isCorrect === true)
const haveImageOrContent = haveOneAnswerRight && values?.answers?.some((item:any)=> !(item?.content) && !(item.content_image) ) const haveImageOrContent = haveOneAnswerRight && values?.answers?.some((item: any) => !(item?.content) && !(item.content_image))
const content = values.content ; const content = values.content;
const content_image = values.content_image ; const content_image = values.content_image;
const haveContentOrContentImage = !!content || !!content_image ; const haveContentOrContentImage = !!content || !!content_image;
console.log(haveImageOrContent,"haveImageOrContent"); console.log(haveImageOrContent, "haveImageOrContent");
if(!haveContentOrContentImage){ if (!haveContentOrContentImage) {
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`); toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false; return false;
} }
if(!haveMoreThanOneAnswer){
toast.error(t("validation.it_should_have_more_than_one_answers")) ;
return false ;
}
if(!haveOneAnswerRight){
toast.error(t("validation.it_should_have_more_than_one_correct_answers")) ;
return false ;
}
if(haveImageOrContent){
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer"))
return false
}
console.log(1);
if(isValid){
handleSubmit(values)
}
}
const handleValidateBaseQuestion = (values: any,isValid:boolean,handleSubmit:any) => {
const content = values.content ;
const content_image = values.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
console.log(2);
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
console.log(1);
const isValidate = values?.Questions?.every((Question: any, QuestionsIndex: number) => {
const content = Question.content ;
const content_image = Question.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
//// answers
const answers = Question?.answers;
const haveAnswers = answers?.length > 0;
const haveMoreThanOneAnswer = haveAnswers && answers?.length > 1;
const haveOneAnswerRight = haveMoreThanOneAnswer && answers?.some((item: any) => item?.isCorrect === 1 || item.isCorrect === true);
const haveImageOrContent = haveOneAnswerRight && answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
if (!haveAnswers) {
toast.error(t("validation.it_should_have_more_than_one_answers"));
return false;
}
if (!haveMoreThanOneAnswer) { if (!haveMoreThanOneAnswer) {
toast.error(t("validation.it_should_have_more_than_one_answers")); toast.error(t("validation.it_should_have_more_than_one_answers"));
return false; return false;
} }
if (!haveOneAnswerRight) { if (!haveOneAnswerRight) {
toast.error(t("validation.it_should_have_more_than_one_correct_answers")); toast.error(t("validation.it_should_have_more_than_one_correct_answers"));
return false; return false;
} }
if (haveImageOrContent) {
if(haveImageOrContent){
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer")) toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer"))
return false return false
} }
return true console.log(1);
});
console.log(1); if (isValid) {
handleSubmit(values)
if(isValid && isValidate){ }
console.log(2);
handleSubmit(values)
}
};
const handleNavigateToPage = () => { }
const cleanedUrl = location.pathname.replace(/\/Question\/\d+$/, ""); const handleValidateBaseQuestion = (values: any, isValid: boolean, handleSubmit: any) => {
navigate(cleanedUrl); const content = values.content;
}; const content_image = values.content_image;
const haveContentOrContentImage = !!content || !!content_image;
console.log(2);
if (!haveContentOrContentImage) {
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
console.log(1);
const isValidate = values?.Questions?.every((Question: any, QuestionsIndex: number) => {
const content = Question.content;
const content_image = Question.content_image;
const haveContentOrContentImage = !!content || !!content_image;
if (!haveContentOrContentImage) {
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
//// answers
const answers = Question?.answers;
const haveAnswers = answers?.length > 0;
const haveMoreThanOneAnswer = haveAnswers && answers?.length > 1;
const haveOneAnswerRight = haveMoreThanOneAnswer && answers?.some((item: any) => item?.isCorrect === 1 || item.isCorrect === true);
const haveImageOrContent = haveOneAnswerRight && answers?.some((item: any) => !(item?.content) && !(item.content_image))
if (!haveAnswers) {
toast.error(t("validation.it_should_have_more_than_one_answers"));
return false;
}
if (!haveMoreThanOneAnswer) {
toast.error(t("validation.it_should_have_more_than_one_answers"));
return false;
}
if (!haveOneAnswerRight) {
toast.error(t("validation.it_should_have_more_than_one_correct_answers"));
return false;
}
if (haveImageOrContent) {
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer"))
return false
}
return true
});
console.log(1);
if (isValid && isValidate) {
console.log(2);
handleSubmit(values)
}
};
useEffect(() => { useEffect(() => {
if (isSuccess) { if (isSuccess) {
@ -302,31 +284,6 @@ const handleNavigateToPage = () => {
} }
}, [isSuccess]); }, [isSuccess]);
const onChangeHint: CheckboxProps['onChange'] = (e) => {
setShowHint(e.target.checked);
localStorage?.setItem(LocalStorageEnum.HINT_INPUT,e.target.checked ? "true" : "false" )
};
const onChangeLatexOption: CheckboxProps['onChange'] = (e) => {
setShowLatexOption(e.target.checked);
localStorage?.setItem(LocalStorageEnum.LATEX_OPTION_INPUT,e.target.checked ? "true" : "false" )
};
const contentSetting = (
<div>
<Checkbox checked={ShowHint} onChange={onChangeHint}>
{ t("header.show_hint")}
</Checkbox>
<Checkbox checked={ShowLatexOption} onChange={onChangeLatexOption}>
{ t("header.show_MMl")}
</Checkbox>
</div>
);
@ -337,119 +294,13 @@ const handleNavigateToPage = () => {
} }
if (objectToEdit?.isBase) { if (objectToEdit?.isBase) {
return ( return (
<BaseFormContainer t={t} Loading={Loading} handleSubmit={handleSubmit} handleValidateBaseQuestion={handleValidateBaseQuestion} objectToEdit={objectToEdit} />
<div className="QuestionPractical">
<header>
<MdOutlineArrowForwardIos onClick={handleNavigateToPage} /> {t("header.edit_question")}
</header>
<div className="exercise_add">
<Formik
onSubmit={handleSubmit}
initialValues={getInitialValuesBase(objectToEdit)}
validationSchema={getValidationSchemaBase}
enableReinitialize
>
{({ values,isValid,handleSubmit }) => (
<Form className="w-100">
<main className="w-100 exercise_add_main">
{/* <Header/> */}
<header className="exercise_add_header mb-4">
<div>
{t("practical.edit")} {t("models.exercise")}{" "}
</div>
<div className="SettingEdit">
<Popover trigger="click" content={contentSetting}>
<SettingFilled/>
</Popover>
<div>{t("header.exercise")}</div>
</div>
</header>
<BaseForm />
<div className="exercise_add_buttons">
<div onClick={handleCancel}>{t("practical.back")}</div>
<button disabled={Loading} className="relative" type="button"
onClick={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit) }}
onSubmit={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit) }}
> {t("practical.edit")}
{Loading && (
<span className="Spinier_Div">
<Spin />
</span>
)}
</button>
</div>
</main>
</Form>
)}
</Formik>
</div>
</div>
); );
} }
return ( return (
<FormContainer t={t} Loading={Loading} handleSubmit={handleSubmit} handleValidateSingleQuestion={handleValidateSingleQuestion} objectToEdit={objectToEdit} />
<div className="QuestionPractical">
<header>
<MdOutlineArrowForwardIos onClick={handleNavigateToPage} /> {t("header.edit_question")}
</header>
<div className="exercise_add">
<Formik
enableReinitialize={true}
initialValues={getInitialValues(objectToEdit)}
validationSchema={getValidationSchema}
onSubmit={(values) => {
handleSubmit(values);
}}
>
{({ values , dirty,isValid,handleSubmit }) => (
<Form className="w-100">
<main className="w-100 exercise_add_main">
{/* <Header/> */}
<header className="exercise_add_header mb-4">
<div>
{t("practical.edit")} {t("models.exercise")}{" "}
</div>
<div className="SettingEdit">
<Popover trigger="click" content={contentSetting}>
<SettingFilled/>
</Popover>
<div>{t("header.exercise")}</div>
</div>
</header>
<ModelForm />
<div className="exercise_add_buttons">
<div onClick={handleCancel}>{t("practical.back")}</div>
<div
className="relative"
onClick={()=>{ Loading ? ()=>{} : handleValidateSingleQuestion(values,isValid,handleSubmit) }}
> {t("practical.edit")}
{Loading && (
<span className="Spinier_Div">
<Spin />
</span>
)}
</div>
</div>
</main>
</Form>
)}
</Formik>
</div>
</div>
); );
}; };

View File

@ -0,0 +1,72 @@
import { Form, Formik, useFormikContext } from 'formik'
import React from 'react'
import { useTranslation } from 'react-i18next'
import { MdOutlineArrowForwardIos } from 'react-icons/md'
import { getInitialValuesBase, getValidationSchemaBase } from '../../formUtil'
import Header from '../../../../../Components/exercise/Header'
import { useNavigate } from 'react-router-dom'
import { Spin } from 'antd'
import BaseForm from "../../Model/Malty/Form";
const BaseFormContainer = ({handleFormSubmit,Loading,handleValidateBaseQuestion}:{handleFormSubmit:any,Loading:any,handleValidateBaseQuestion:any}) => {
const [t] = useTranslation()
const navigate = useNavigate();
const handleNavigateToPage = () => {
const cleanedUrl = location.pathname?.replace("/Question/add", "");
navigate(cleanedUrl);
};
const handleCancel = () => {
navigate(-1);
};
return (
<div className="QuestionPractical">
<header>
<MdOutlineArrowForwardIos onClick={handleNavigateToPage} /> {t("header.add_new_question")}
</header>
<div className="exercise_add">
<Formik
onSubmit={handleFormSubmit}
initialValues={getInitialValuesBase({} as any)}
validationSchema={getValidationSchemaBase}
enableReinitialize
>
{({ values,isValid,handleSubmit ,dirty}) => (
<Form className="w-100">
<main className="w-100 exercise_add_main">
<Header />
<BaseForm />
<div className="exercise_add_buttons">
<div onClick={handleCancel}>{t("practical.back")}</div>
<button disabled={Loading} className={`relative ${dirty ? "" : "disabled"}`} type="button"
onClick={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit,t) }}
>
{t("practical.add")}
{Loading && (
<span className="Spinier_Div">
<Spin />
</span>
)}
</button>
</div>
</main>
</Form>
)}
</Formik>
</div>
</div>
)
}
export default BaseFormContainer

View File

@ -0,0 +1,72 @@
import { Form, Formik, useFormikContext } from 'formik'
import { useTranslation } from 'react-i18next'
import { MdOutlineArrowForwardIos } from 'react-icons/md'
import { getInitialValues, getValidationSchema } from '../../formUtil'
import Header from '../../../../../Components/exercise/Header'
import { useNavigate } from 'react-router-dom'
import { Spin } from 'antd'
import ModelForm from "../../Model/ModelForm";
const FormContainer = ({handleFormSubmit,Loading,handleValidateSingleQuestion}:{handleFormSubmit:any,Loading:any,handleValidateSingleQuestion:any}) => {
const [t] = useTranslation()
const navigate = useNavigate();
const handleNavigateToPage = () => {
const cleanedUrl = location.pathname?.replace("/Question/add", "");
navigate(cleanedUrl);
};
const handleCancel = () => {
navigate(-1);
};
return (
<div className="QuestionPractical">
<header>
<MdOutlineArrowForwardIos onClick={handleNavigateToPage} /> {t("header.add_new_question")}
</header>
<div className="exercise_add">
<Formik
enableReinitialize={true}
initialValues={getInitialValues({} as any)}
validationSchema={getValidationSchema}
validateOnMount={true}
onSubmit={(values) => {
handleFormSubmit(values);
}}
>
{({ values,isValid ,handleSubmit,dirty}) => (
<Form className="w-100">
<main className="w-100 exercise_add_main">
<Header />
<ModelForm />
<div className="exercise_add_buttons">
<div onClick={handleCancel}>{t("practical.back")}</div>
<div
className={`relative ${dirty ? "" : "disabled"}`}
onClick={()=>{ Loading ? ()=>{} : handleValidateSingleQuestion(values,isValid,handleSubmit,t) }}
>
{t("practical.add")}
{Loading && (
<span className="Spinier_Div">
<Spin />
</span>
)}
</div>
</div>
</main>
</Form>
)}
</Formik>
</div>
</div>
)
}
export default FormContainer

View File

@ -0,0 +1,100 @@
import { toast } from "react-toastify";
export const handleValidateSingleQuestion = (values:any,isValid:boolean,handleSubmit:any,t:any)=>{
const haveMoreThanOneAnswer = values?.answers?.length > 1;
const haveOneAnswerRight = haveMoreThanOneAnswer && values?.answers?.some((item:any)=> item?.isCorrect === 1 || item.isCorrect === true )
const haveImageOrContent = haveOneAnswerRight && values?.answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
const content = values.content ;
const content_image = values.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
console.log(haveImageOrContent,"haveImageOrContent");
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
if(!haveMoreThanOneAnswer){
toast.error(t("validation.it_should_have_more_than_one_answers")) ;
return false ;
}
if(!haveOneAnswerRight){
toast.error(t("validation.it_should_have_more_than_one_correct_answers")) ;
return false ;
}
if(haveImageOrContent){
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer"))
return false
}
console.log(1);
if(isValid){
handleSubmit(values)
}
}
export const handleValidateBaseQuestion = (values: any,isValid:boolean,handleSubmit:any,t:any) => {
const content = values.content ;
const content_image = values.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
console.log(2);
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
console.log(1);
const isValidate = values?.Questions?.every((Question: any, QuestionsIndex: number) => {
const content = Question.content ;
const content_image = Question.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
//// answers
const answers = Question?.answers;
const haveAnswers = answers?.length > 0;
const haveMoreThanOneAnswer = haveAnswers && answers?.length > 1;
const haveOneAnswerRight = haveMoreThanOneAnswer && answers?.some((item: any) => item?.isCorrect === 1 || item.isCorrect === true);
const haveImageOrContent = haveOneAnswerRight && answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
if (!haveAnswers) {
toast.error(t("validation.it_should_have_more_than_one_answers"));
return false;
}
if (!haveMoreThanOneAnswer) {
toast.error(t("validation.it_should_have_more_than_one_answers"));
return false;
}
if (!haveOneAnswerRight) {
toast.error(t("validation.it_should_have_more_than_one_correct_answers"));
return false;
}
if(haveImageOrContent){
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer"))
return false
}
return true
});
console.log(1);
if(isValid && isValidate){
console.log(2);
handleSubmit(values)
}
};

View File

@ -0,0 +1,108 @@
import { Form, Formik } from 'formik';
import React from 'react'
import { MdOutlineArrowForwardIos } from 'react-icons/md';
import { useLocation, useNavigate } from 'react-router-dom';
import { getInitialValuesBase, getValidationSchemaBase } from '../../formUtil';
import { Checkbox, Popover, Spin } from 'antd';
import { SettingFilled } from '@ant-design/icons';
import { CheckboxProps } from 'antd/lib';
import { LocalStorageEnum } from '../../../../../enums/LocalStorageEnum';
import { useObjectToEdit } from '../../../../../zustand/ObjectToEditState';
import ModelForm from "../../Model/Malty/Form";
const BaseFormContainer = ({objectToEdit,handleSubmit,Loading,handleValidateBaseQuestion,t}:{objectToEdit:any,handleSubmit:any,Loading:any,handleValidateBaseQuestion:any,t:any}) => {
const location = useLocation();
const navigate = useNavigate();
const { ShowHint,setShowHint , ShowLatexOption,setShowLatexOption } =
useObjectToEdit();
const handleCancel = () => {
navigate(-1);
};
const handleNavigateToPage = () => {
const cleanedUrl = location.pathname.replace(/\/Question\/\d+$/, "");
navigate(cleanedUrl);
};
const onChangeHint: CheckboxProps['onChange'] = (e) => {
setShowHint(e.target.checked);
localStorage?.setItem(LocalStorageEnum.HINT_INPUT,e.target.checked ? "true" : "false" )
};
const onChangeLatexOption: CheckboxProps['onChange'] = (e) => {
setShowLatexOption(e.target.checked);
localStorage?.setItem(LocalStorageEnum.LATEX_OPTION_INPUT,e.target.checked ? "true" : "false" )
};
const contentSetting = (
<div>
<Checkbox checked={ShowHint} onChange={onChangeHint}>
{ t("header.show_hint")}
</Checkbox>
<Checkbox checked={ShowLatexOption} onChange={onChangeLatexOption}>
{ t("header.show_MMl")}
</Checkbox>
</div>
);
return (
<div className="QuestionPractical">
<header>
<MdOutlineArrowForwardIos onClick={handleNavigateToPage} /> {t("header.edit_question")}
</header>
<div className="exercise_add">
<Formik
onSubmit={handleSubmit}
initialValues={getInitialValuesBase(objectToEdit)}
validationSchema={getValidationSchemaBase}
enableReinitialize
>
{({ values,isValid,handleSubmit,dirty }) => (
<Form className="w-100">
<main className="w-100 exercise_add_main">
{/* <Header/> */}
<header className="exercise_add_header mb-4">
<div>
{t("practical.edit")} {t("models.exercise")}{" "}
</div>
<div className="SettingEdit">
<Popover trigger="click" content={contentSetting}>
<SettingFilled/>
</Popover>
<div>{t("header.exercise")}</div>
</div>
</header>
<ModelForm />
<div className="exercise_add_buttons">
<div onClick={handleCancel}>{t("practical.back")}</div>
<button disabled={Loading} className={`relative ${dirty ? "" : "disabled"}`} type="button"
onClick={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit) }}
onSubmit={()=>{handleValidateBaseQuestion(values,isValid,handleSubmit) }}
> {t("practical.edit")}
{Loading && (
<span className="Spinier_Div">
<Spin />
</span>
)}
</button>
</div>
</main>
</Form>
)}
</Formik>
</div>
</div>
)
}
export default BaseFormContainer

View File

@ -0,0 +1,110 @@
import { Form, Formik } from 'formik';
import React from 'react'
import { MdOutlineArrowForwardIos } from 'react-icons/md';
import { useLocation, useNavigate } from 'react-router-dom';
import { getInitialValues, getValidationSchema } from '../../formUtil';
import { Checkbox, Popover, Spin } from 'antd';
import { SettingFilled } from '@ant-design/icons';
import { CheckboxProps } from 'antd/lib';
import { LocalStorageEnum } from '../../../../../enums/LocalStorageEnum';
import { useObjectToEdit } from '../../../../../zustand/ObjectToEditState';
import ModelForm from "../../Model/ModelForm";
const FormContainer = ({objectToEdit,handleSubmit,Loading,handleValidateSingleQuestion,t}:{objectToEdit:any,handleSubmit:any,Loading:any,handleValidateSingleQuestion:any,t:any}) => {
const location = useLocation();
const navigate = useNavigate();
const { ShowHint,setShowHint , ShowLatexOption,setShowLatexOption } =
useObjectToEdit();
const handleCancel = () => {
navigate(-1);
};
const handleNavigateToPage = () => {
const cleanedUrl = location.pathname.replace(/\/Question\/\d+$/, "");
navigate(cleanedUrl);
};
const onChangeHint: CheckboxProps['onChange'] = (e) => {
setShowHint(e.target.checked);
localStorage?.setItem(LocalStorageEnum.HINT_INPUT,e.target.checked ? "true" : "false" )
};
const onChangeLatexOption: CheckboxProps['onChange'] = (e) => {
setShowLatexOption(e.target.checked);
localStorage?.setItem(LocalStorageEnum.LATEX_OPTION_INPUT,e.target.checked ? "true" : "false" )
};
const contentSetting = (
<div>
<Checkbox checked={ShowHint} onChange={onChangeHint}>
{ t("header.show_hint")}
</Checkbox>
<Checkbox checked={ShowLatexOption} onChange={onChangeLatexOption}>
{ t("header.show_MMl")}
</Checkbox>
</div>
);
return (
<div className="QuestionPractical">
<header>
<MdOutlineArrowForwardIos onClick={handleNavigateToPage} /> {t("header.edit_question")}
</header>
<div className="exercise_add">
<Formik
enableReinitialize={true}
initialValues={getInitialValues(objectToEdit)}
validationSchema={getValidationSchema}
onSubmit={(values) => {
handleSubmit(values);
}}
>
{({ values , dirty,isValid,handleSubmit }) => (
<Form className="w-100">
<main className="w-100 exercise_add_main">
{/* <Header/> */}
<header className="exercise_add_header mb-4">
<div>
{t("practical.edit")} {t("models.exercise")}{" "}
</div>
<div className="SettingEdit">
<Popover trigger="click" content={contentSetting}>
<SettingFilled/>
</Popover>
<div>{t("header.exercise")}</div>
</div>
</header>
<ModelForm />
<div className="exercise_add_buttons">
<div onClick={handleCancel}>{t("practical.back")}</div>
<div
className={`relative ${dirty ? "" : "disabled"}`}
onClick={()=>{ Loading ? ()=>{} : handleValidateSingleQuestion(values,isValid,handleSubmit,t) }}
> {t("practical.edit")}
{Loading && (
<span className="Spinier_Div">
<Spin />
</span>
)}
</div>
</div>
</main>
</Form>
)}
</Formik>
</div>
</div>
)
}
export default FormContainer

View File

@ -0,0 +1,100 @@
import { toast } from "react-toastify";
export const handleValidateSingleQuestion = (values:any,isValid:boolean,handleSubmit:any,t:any)=>{
const haveMoreThanOneAnswer = values?.answers?.length > 1;
const haveOneAnswerRight = haveMoreThanOneAnswer && values?.answers?.some((item:any)=> item?.isCorrect === 1 || item.isCorrect === true )
const haveImageOrContent = haveOneAnswerRight && values?.answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
const content = values.content ;
const content_image = values.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
console.log(haveImageOrContent,"haveImageOrContent");
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
if(!haveMoreThanOneAnswer){
toast.error(t("validation.it_should_have_more_than_one_answers")) ;
return false ;
}
if(!haveOneAnswerRight){
toast.error(t("validation.it_should_have_more_than_one_correct_answers")) ;
return false ;
}
if(haveImageOrContent){
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer"))
return false
}
console.log(1);
if(isValid){
handleSubmit(values)
}
}
export const handleValidateBaseQuestion = (values: any,isValid:boolean,handleSubmit:any,t:any) => {
const content = values.content ;
const content_image = values.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
console.log(2);
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
console.log(1);
const isValidate = values?.Questions?.every((Question: any, QuestionsIndex: number) => {
const content = Question.content ;
const content_image = Question.content_image ;
const haveContentOrContentImage = !!content || !!content_image ;
if(!haveContentOrContentImage){
toast.error(`${t("validation.one_of_image_and_content_should_be_enter_in_question")}`);
return false;
}
//// answers
const answers = Question?.answers;
const haveAnswers = answers?.length > 0;
const haveMoreThanOneAnswer = haveAnswers && answers?.length > 1;
const haveOneAnswerRight = haveMoreThanOneAnswer && answers?.some((item: any) => item?.isCorrect === 1 || item.isCorrect === true);
const haveImageOrContent = haveOneAnswerRight && answers?.some((item:any)=> !(item?.content) && !(item.content_image) )
if (!haveAnswers) {
toast.error(t("validation.it_should_have_more_than_one_answers"));
return false;
}
if (!haveMoreThanOneAnswer) {
toast.error(t("validation.it_should_have_more_than_one_answers"));
return false;
}
if (!haveOneAnswerRight) {
toast.error(t("validation.it_should_have_more_than_one_correct_answers"));
return false;
}
if(haveImageOrContent){
toast.error(t("validation.one_of_image_and_content_should_be_enter_in_answer"))
return false
}
return true
});
console.log(1);
if(isValid && isValidate){
console.log(2);
handleSubmit(values)
}
};

View File

@ -21,7 +21,6 @@ const ChoiceFields = React.memo(
setFieldValue:any; setFieldValue:any;
values:any values:any
}) => { }) => {
console.log(567)
const [t] = useTranslation(); const [t] = useTranslation();
const { ShowHint } = useObjectToEdit(); const { ShowHint } = useObjectToEdit();
const handleDeleteChoice = () => { const handleDeleteChoice = () => {
@ -120,7 +119,6 @@ const ChoiceFields = React.memo(
} }
, (prevProps, nextProps) => { , (prevProps, nextProps) => {
console.log(prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[prevProps?.index] === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[prevProps?.index]); console.log(prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[prevProps?.index] === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[prevProps?.index]);
console.log(2255);
return prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[prevProps?.index] === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[prevProps?.index]; return prevProps.values?.Questions?.[prevProps?.parent_index]?.answers?.[prevProps?.index] === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers?.[prevProps?.index];
}); });

View File

@ -113,8 +113,6 @@ const Choices = React.memo( ({setFieldValue ,values,parent_index }:any) => {
</> </>
); );
}, (prevProps, nextProps) => { }, (prevProps, nextProps) => {
console.log(prevProps.values?.Questions?.[prevProps?.parent_index]?.answers === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers);
console.log(22);
return prevProps.values?.Questions?.[prevProps?.parent_index]?.answers === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers; return prevProps.values?.Questions?.[prevProps?.parent_index]?.answers === nextProps.values?.Questions?.[nextProps?.parent_index]?.answers;
}); });

View File

@ -10,6 +10,7 @@ import { CombinationKeyEnum } from "../../../../../enums/CombinationKeyEnum";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import MainInputs from "./components/MainInputs"; import MainInputs from "./components/MainInputs";
import Questions from "./components/Questions"; import Questions from "./components/Questions";
import useUnsavedChangesWarning from "../../../../../Hooks/useUnsavedChangesWarning";
const Form = () => { const Form = () => {
const formik = useFormikContext<any>(); const formik = useFormikContext<any>();
@ -64,6 +65,8 @@ const Form = () => {
const lastQuestions = formik?.values?.Questions?.length - 1; const lastQuestions = formik?.values?.Questions?.length - 1;
////////////// hooks
useKeyCombination( useKeyCombination(
{ ctrlKey: true, shiftKey: true, code: CombinationKeyEnum.CHOICE }, { ctrlKey: true, shiftKey: true, code: CombinationKeyEnum.CHOICE },
() => { () => {
@ -77,8 +80,10 @@ const lastQuestions = formik?.values?.Questions?.length - 1;
handleAddQuestion(true); handleAddQuestion(true);
}, },
); );
useUnsavedChangesWarning(formik.dirty);
//////////////
useEffect(() => { useEffect(() => {
if (Success) { if (Success) {
formik.resetForm() formik.resetForm()

View File

@ -12,6 +12,7 @@ import { CombinationKeyEnum } from "../../../../enums/CombinationKeyEnum";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import LaTeXInputMemo from "../../../../Components/LatextInput/LaTeXInputMemo"; import LaTeXInputMemo from "../../../../Components/LatextInput/LaTeXInputMemo";
import ImageBoxFieldMemo from "../../../../Components/CustomFields/ImageBoxField/ImageBoxFieldMemo"; import ImageBoxFieldMemo from "../../../../Components/CustomFields/ImageBoxField/ImageBoxFieldMemo";
import useUnsavedChangesWarning from "../../../../Hooks/useUnsavedChangesWarning";
const Form = () => { const Form = () => {
const [t] = useTranslation(); const [t] = useTranslation();
@ -33,6 +34,10 @@ const Form = () => {
} }
}; };
////////////// hooks
useKeyCombination( useKeyCombination(
{ ctrlKey: true, shiftKey: true, code: CombinationKeyEnum.CHOICE }, { ctrlKey: true, shiftKey: true, code: CombinationKeyEnum.CHOICE },
() => { () => {
@ -40,14 +45,16 @@ const Form = () => {
}, },
); );
useUnsavedChangesWarning(formik.dirty);
useEffect(() => { useEffect(() => {
if (Success) { if (Success) {
formik.resetForm() formik.resetForm()
setSuccess(false); setSuccess(false);
} }
}, [Success]); }, [Success]);
console.log(formik.errors);
return ( return (

View File

@ -6,9 +6,7 @@ const Dummy = () => {
const [t] = useTranslation(); const [t] = useTranslation();
return ( return (
<div className="DummyHomePage"> <div className="DummyHomePage">
</div> </div>
); );
}; };

View File

@ -8,7 +8,7 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
const { setFieldValue } = form; const { setFieldValue } = form;
const [curCentValue, setCurrentValue] = useState(value) const [curCentValue, setCurrentValue] = useState(value)
const handleChangeInput = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => { const handleChangeInput = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setFieldValue(name, e.target.value); // setFieldValue(name, e.target.value);
setCurrentValue(e.target.value) setCurrentValue(e.target.value)
}; };
console.log(name,"name"); console.log(name,"name");
@ -24,6 +24,7 @@ const LaTeXInputMemo: React.FC<any> = React.memo(({ field ,form, label, ...prop
</label> </label>
<div className='LaTeXInputArea'> <div className='LaTeXInputArea'>
<TextArea <TextArea
size="large" size="large"
showCount showCount

View File

@ -114,4 +114,7 @@ svg{
.LaTeXRenderer{ .LaTeXRenderer{
direction: ltr; direction: ltr;
}
.ant-input,.LaTeXInputArea,input{
} }

View File

@ -100,4 +100,9 @@
.transparent_bg{ .transparent_bg{
background: transparent !important; background: transparent !important;
color: #fff !important; color: #fff !important;
}
.disabled{
pointer-events: none;
opacity: 0.6;
} }

View File

@ -52,7 +52,8 @@
"File_size_exceeds_2_MB_limit.":"حجم الملف يتجاوز الحد الأقصى البالغ 2 ميجابايت", "File_size_exceeds_2_MB_limit.":"حجم الملف يتجاوز الحد الأقصى البالغ 2 ميجابايت",
"one_of_image_and_content_should_be_enter_in_answer":"يجب إدخال صورة أو محتوى واحد على الأقل في الاجابة", "one_of_image_and_content_should_be_enter_in_answer":"يجب إدخال صورة أو محتوى واحد على الأقل في الاجابة",
"one_of_image_and_content_should_be_enter_in_question":"يجب إدخال صورة أو محتوى واحد على الأقل في السؤال", "one_of_image_and_content_should_be_enter_in_question":"يجب إدخال صورة أو محتوى واحد على الأقل في السؤال",
"that_is_not_a_valid_mml":"هذا ليس mml صالح" "that_is_not_a_valid_mml":"هذا ليس mml صالح",
"Are_you_sure_you_want_to_leave_Your_changes_may_not_be_saved":"هل أنت متأكد من أنك تريد المغادرة ؟ قد لا يتم حفظ التغييرات التي أجريتها"
}, },
"header": { "header": {
"register_students": "تسجيل الطلاب", "register_students": "تسجيل الطلاب",