fix multy question
This commit is contained in:
parent
6e1e79465f
commit
4f944eab55
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -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"));
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
|
|||
<TextField
|
||||
className="textarea_exercise"
|
||||
placeholder={"choice"}
|
||||
label2={t(`input.choice`) + ` ` + `( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
|
||||
label2={t(`input.choice`) + ` ` +`( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
|
||||
name={index}
|
||||
id={`choice_${index + 1}`}
|
||||
type="TextArea"
|
||||
|
|
|
|||
|
|
@ -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,39 +53,41 @@ 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}
|
||||
/>
|
||||
|
||||
<CheckboxField
|
||||
className=""
|
||||
label="The_correct_answer"
|
||||
name={index}
|
||||
type="Checkbox"
|
||||
parent_index={parent_index}
|
||||
/>
|
||||
<p className="delete_question_options">
|
||||
<FaTrash onClick={handleDeleteChoice} size={17} />
|
||||
</p>
|
||||
<ImageBoxField name={`Questions.${parent_index}.answers.${index}.answer_image`} />
|
||||
|
||||
<div className="answer_status">
|
||||
|
||||
<CheckboxField
|
||||
className=""
|
||||
label="The_correct_answer"
|
||||
name={index}
|
||||
type="Checkbox"
|
||||
parent_index={parent_index}
|
||||
/>
|
||||
<p className="delete_question_options">
|
||||
{t("header.delete_choice")}
|
||||
<GoTrash className="trash_icon" onClick={handleDeleteChoice} size={17} />
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<HintField
|
||||
className=""
|
||||
label="hint"
|
||||
placeholder="hint"
|
||||
name={index}
|
||||
|
||||
parent_index={parent_index}
|
||||
|
||||
|
||||
|
||||
<div className="exercise_form_width">
|
||||
<ValidationField
|
||||
className=" "
|
||||
placeholder="_"
|
||||
name={`Questions.${parent_index}.answers.${index}.hint`}
|
||||
label="hint"
|
||||
type="text"
|
||||
style={{ width: "100%" }}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
|
|
|||
134
src/Pages/Admin/question/Model/Malty/Form.tsx
Normal file
134
src/Pages/Admin/question/Model/Malty/Form.tsx
Normal 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;
|
||||
|
|
@ -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="ChoiceFields">
|
||||
<TextField
|
||||
className="textarea_exercise"
|
||||
placeholder={"choice"}
|
||||
label2={t(`input.question`) + ` ` + `${index + 1}`}
|
||||
name={index}
|
||||
type="TextArea"
|
||||
/>
|
||||
<File
|
||||
className="file_exercise"
|
||||
label={"attachment"}
|
||||
name={index}
|
||||
type="File"
|
||||
/>
|
||||
<CheckboxField
|
||||
className="canAnswersBeShuffled"
|
||||
label={"canAnswersBeShuffled"}
|
||||
name={index}
|
||||
/>
|
||||
<>
|
||||
|
||||
<div className="exercise_forms">
|
||||
<div className="ChoiceFields">
|
||||
<TextField
|
||||
className="textarea_exercise"
|
||||
placeholder={"question"}
|
||||
label2={t(`input.question`) + ` ` + `( ${t(`alphabet.${getCharFromNumber(index)}`)} )`}
|
||||
name={index}
|
||||
id={`question_${index + 1}`}
|
||||
type="TextArea"
|
||||
/>
|
||||
|
||||
<ImageBoxField name={`Questions.${index}.image`} />
|
||||
|
||||
<p className="delete_question_options">
|
||||
<FaTrash onClick={handleDeleteQuestion} size={17} />
|
||||
</p>
|
||||
</div>
|
||||
<div className="answer_status">
|
||||
|
||||
<div>
|
||||
<HintField placeholder={"hint"} name={index} label="hint" id={`hint`} />
|
||||
<p className="delete_question_options">
|
||||
{t("header.delete_question")}
|
||||
<GoTrash className="trash_icon" onClick={handleDeleteQuestion} size={17} />
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
77
src/Pages/Admin/question/Model/Malty/Tags/MaltySelectTag.tsx
Normal file
77
src/Pages/Admin/question/Model/Malty/Tags/MaltySelectTag.tsx
Normal 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;
|
||||
|
|
@ -193,3 +193,7 @@
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
.exercise_forms{
|
||||
width: 100%;
|
||||
}
|
||||
|
|
@ -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": {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user