fix multy question

This commit is contained in:
karimaldeen 2024-09-09 14:36:47 +03:00
parent 6e1e79465f
commit 4f944eab55
10 changed files with 287 additions and 66 deletions

View File

@ -3,14 +3,17 @@ import { Select, Spin } from 'antd';
import { useTranslation } from 'react-i18next';
import { useDebounce } from '../../utils/useDebounce';
import { useGetAllTag } from '../../api/tags';
import { useFormikContext } from 'formik';
const SelectTag: React.FC = () => {
const [searchValue, setSearchValue] = useState<string>('');
const [fieldValue, setFieldValue] = useState<string>('');
const formik = useFormikContext<any>()
const handleChange = (value: string[]) => {
formik.setFieldValue("tags",value)
setSearchValue('');
setFieldValue('');
};
const handleSearch = useDebounce((value: string) => {
@ -35,9 +38,7 @@ const SelectTag: React.FC = () => {
const [t] = useTranslation();
const options = data?.data ?? []
console.log(options,"options");
const additionalData = options?.length < 1 && searchValue.length > 1 && !isLoading ? [{id:`new_${searchValue}`,name:searchValue}] :[];
console.log(additionalData);
return (
<div className='SelectTag'>
@ -66,6 +67,7 @@ const SelectTag: React.FC = () => {
handleBlur();
}
}}
value={formik?.values?.tags ?? []}
/>
</div>
);

View File

@ -16,7 +16,7 @@ import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import Header from "../../../Components/exercise/Header";
import { Question } from "../../../types/Item";
import BaseForm from "./Model/Malty/Add";
import BaseForm from "./Model/Malty/Form";
import ModelForm from "./Model/ModelForm";
const AcceptModal = lazy(() => import("./Model/AcceptModal"));

View File

@ -22,7 +22,7 @@ import { useObjectToEdit } from "../../../zustand/ObjectToEditState";
import { removeStringKeys } from "../../../utils/removeStringKeys";
import SpinContainer from "../../../Components/Layout/SpinContainer";
import ModelForm from "./Model/ModelForm";
import BaseForm from "./Model/Malty/Edit";
import BaseForm from "./Model/Malty/Form";
import { Question } from "../../../types/Item";
import { toast } from "react-toastify";
import useSetPageTitle from "../../../Hooks/useSetPageTitle";

View File

@ -10,6 +10,8 @@ import File from "./File";
import { FaTrash } from "react-icons/fa";
import { toast } from "react-toastify";
import HintField from "./HintField";
import ImageBoxField from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
import { GoTrash } from "react-icons/go";
const ChoiceFields = ({
index,
@ -51,18 +53,15 @@ const ChoiceFields = ({
<TextField
className="textarea_exercise"
placeholder={"choice"}
label2={t(`input.choice`) + ` ` + `(${getCharFromNumber(index)})`}
label2={t(`input.choice`) + ` ` + `( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
name={index}
parent_index={parent_index}
type="TextArea"
/>
<File
className="file_exercise"
label={"attachment"}
name={index}
type="File"
parent_index={parent_index}
/>
<ImageBoxField name={`Questions.${parent_index}.answers.${index}.answer_image`} />
<div className="answer_status">
<CheckboxField
className=""
@ -72,18 +71,23 @@ const ChoiceFields = ({
parent_index={parent_index}
/>
<p className="delete_question_options">
<FaTrash onClick={handleDeleteChoice} size={17} />
{t("header.delete_choice")}
<GoTrash className="trash_icon" onClick={handleDeleteChoice} size={17} />
</p>
</div>
<div>
<HintField
</div>
<div className="exercise_form_width">
<ValidationField
className=" "
placeholder="_"
name={`Questions.${parent_index}.answers.${index}.hint`}
label="hint"
placeholder="hint"
name={index}
parent_index={parent_index}
type="text"
style={{ width: "100%" }}
/>
</div>
</>

View File

@ -0,0 +1,134 @@
import { Col, Row } from "reactstrap";
import React, { useEffect } from "react";
import ValidationField from "../../../../../Components/ValidationField/ValidationField";
import { useFormikContext } from "formik";
import { useModalState } from "../../../../../zustand/Modal";
import ChoiceFields from "./ChoiceField/ChoiceFields";
import { FaCirclePlus } from "react-icons/fa6";
import { Choice } from "../../../../../types/Item";
import { useTranslation } from "react-i18next";
import DynamicTags from "./Tags/DynamicTags";
import QuestionFIeld from "./QuestionFIeld/QuestionFIeld";
import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
import Choices from "./ChoiceField/Choices";
import ImageBoxField from "../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
import MaltySelectTag from "./Tags/MaltySelectTag";
const Form = () => {
const formik = useFormikContext<any>();
const { setSuccess, Success, setSavedQuestionData } = useObjectToEdit();
useEffect(() => {
if (Success) {
formik.setErrors({});
formik.resetForm({ values: {} });
setSuccess(false);
}
}, [Success]);
useEffect(() => {
setSavedQuestionData(formik.values);
}, [formik?.values]);
// console.log(formik?.errors);
const handleAddChoice = (parent_index: number) => {
console.log(parent_index);
formik.setFieldValue(`Questions.[${parent_index}].answers`, [
...((formik?.values as any)?.Questions?.[parent_index]
.answers as Choice[]),
{
answer: null,
answer_image: null,
isCorrect: 0,
},
]);
};
const handleAddQuestion = () => {
formik.setFieldValue("Questions", [
...((formik?.values as any)?.Questions as Choice[]),
{
content: "",
image: "",
parent: "",
isBase: 0,
// max_mark: 1,
// min_mark_to_pass: 1,
answers: [{ answer: null, answer_image: null, isCorrect: 0 }],
tags: [],
},
]);
const max_mark = formik?.values?.max_mark + 1;
formik.setFieldValue("max_mark", max_mark);
};
const [t] = useTranslation();
return (
<Row className="w-100 exercise_form_container">
<div className="exercise_form">
<ValidationField className="textarea_exercise" name="content" label="main_question" type="TextArea" />
<ImageBoxField name="image" />
<div></div>
</div>
<div className=" flex "></div>
{((formik?.values as any)?.Questions || [])?.map(
(item: Choice, parent_index: number) => {
return (
<div key={parent_index}>
<div className="exercise_form">
<QuestionFIeld
key={parent_index}
index={parent_index}
data={item}
/>
</div>
<Choices parent_index={parent_index} />
{formik?.values?.Questions?.[parent_index]?.answers
?.length < 5 && (
<p className="add_new_button">
<FaCirclePlus
onClick={() => handleAddChoice(parent_index)}
size={23}
/>{" "}
{t("header.add_new_choice")}
</p>
)}
<div className="exercise_form_width">
<ValidationField
className=" "
placeholder="_"
name={`answers.${parent_index}.hint`}
label="hint_question"
type="text"
style={{ width: "100%" }}
/>
<MaltySelectTag parent_index={parent_index} />
</div>
</div>
);
},
)}
<p className="add_new_button">
<FaCirclePlus onClick={handleAddQuestion} size={23} />{" "}
{t("header.add_new_question")}
</p>
</Row>
);
};
export default Form;

View File

@ -11,6 +11,8 @@ import { useObjectToEdit } from "../../../../../../zustand/ObjectToEditState";
import { toast } from "react-toastify";
import CheckboxField from "./CheckboxField";
import HintField from "./HintField";
import ImageBoxField from "../../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
import { GoTrash } from "react-icons/go";
const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
const formik = useFormikContext<any>();
@ -33,39 +35,36 @@ const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
};
return (
<div className="d-c">
<>
<div className="exercise_forms">
<div className="ChoiceFields">
<TextField
className="textarea_exercise"
placeholder={"choice"}
label2={t(`input.question`) + ` ` + `${index + 1}`}
placeholder={"question"}
label2={t(`input.question`) + ` ` + `( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
name={index}
id={`question_${index + 1}`}
type="TextArea"
/>
<File
className="file_exercise"
label={"attachment"}
name={index}
type="File"
/>
<CheckboxField
className="canAnswersBeShuffled"
label={"canAnswersBeShuffled"}
name={index}
/>
<ImageBoxField name={`Questions.${index}.image`} />
<div className="answer_status">
<p className="delete_question_options">
<FaTrash onClick={handleDeleteQuestion} size={17} />
{t("header.delete_question")}
<GoTrash className="trash_icon" onClick={handleDeleteQuestion} size={17} />
</p>
</div>
<div>
<HintField placeholder={"hint"} name={index} label="hint" id={`hint`} />
</div>
</div>
</div>
</div>
</>
);
};

View File

@ -0,0 +1,77 @@
import React, { useState, useMemo } from 'react';
import { Select, Spin } from 'antd';
import { useTranslation } from 'react-i18next';
import { useFormikContext } from 'formik';
import { useDebounce } from '../../../../../../utils/useDebounce';
import { useGetAllTag } from '../../../../../../api/tags';
const MaltySelectTag = ({parent_index}:{parent_index:number}) => {
const [searchValue, setSearchValue] = useState<string>('');
const [fieldValue, setFieldValue] = useState<string>('');
const formik = useFormikContext<any>();
const values = formik?.values?.Questions?.[parent_index]?.tags;
const handleChange = (value: string[]) => {
formik.setFieldValue(`Questions.[${parent_index}].tags`,value)
setSearchValue('');
setFieldValue('');
};
const handleSearch = useDebounce((value: string) => {
setSearchValue(value);
});
const handleFieldChange = (value: string) => {
setFieldValue(value);
};
const handleBlur = () => {
setSearchValue('');
setFieldValue('');
};
const { data, isLoading } = useGetAllTag({
name: searchValue,
});
const [t] = useTranslation();
const options = data?.data ?? []
const additionalData = options?.length < 1 && searchValue.length > 1 && !isLoading ? [{id:`new_${searchValue}`,name:searchValue}] :[];
return (
<div className='SelectTag'>
<label htmlFor="">
{t("models.tag")}
</label>
<Select
mode="multiple"
allowClear
style={{ width: '100%' ,height:"40px"}}
placeholder=""
fieldNames={{ label: 'name', value: 'id' }}
onChange={handleChange}
options={[...options,...additionalData]}
filterOption={false}
loading={isLoading}
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
onSearch={(value) => {
handleSearch(value);
handleFieldChange(value);
}}
searchValue={fieldValue}
onDropdownVisibleChange={(open) => {
if (!open) {
handleBlur();
}
}}
value={values ?? []}
/>
</div>
);
};
export default MaltySelectTag;

View File

@ -193,3 +193,7 @@
}
}
.exercise_forms{
width: 100%;
}

View File

@ -109,7 +109,8 @@
"delete_choice": "حذف الخيار",
"add": "إضافة",
"notification": "الاشعارات",
"change_language": "تغيير اللغة"
"change_language": "تغيير اللغة",
"delete_question":"حذف السؤال"
},
"columns": {
"id": "الرقم التعريفي",
@ -374,8 +375,8 @@
"id": "الرقم التعريفي",
"icon": "الايقونة",
"answer_content":"نص السؤال",
"hint":"شرح السؤال",
"hint_question":"شرح الاختيار",
"hint":"شرح الاختيار",
"hint_question":"شرح السؤال",
"_":""
},
"select": {