From 8d9a38e1a93dd1d18990974d56b3f5b7feb83997 Mon Sep 17 00:00:00 2001 From: karimalden Date: Wed, 26 Jun 2024 01:46:13 +0300 Subject: [PATCH] add_baseQuestion --- .../ValidationField/View/Default.tsx | 9 +- src/Components/ValidationField/utils/types.ts | 1 + src/Components/exercise/Header.tsx | 38 ++++ src/Pages/Auth/LoginForm.tsx | 2 +- src/Pages/Auth/formutils.ts | 6 - src/Pages/Unit/Model/AddModel.tsx | 2 +- src/Pages/Unit/Model/AddUnit.tsx | 9 - src/Pages/Unit/Model/EditModel.tsx | 2 +- src/Pages/Unit/Model/EditUnit.tsx | 9 - src/Pages/Unit/Model/formUtil.ts | 3 - src/Pages/Unit/useTableColumns.tsx | 10 +- src/Pages/lesson/Model/Add.tsx | 2 +- src/Pages/lesson/Model/AddModel.tsx | 2 +- src/Pages/lesson/Model/Edit.tsx | 2 +- src/Pages/lesson/Model/EditModel.tsx | 2 +- src/Pages/lesson/useTableColumns.tsx | 9 - src/Pages/question/AddPage.tsx | 134 ++++++++++++ src/Pages/question/EditPage.tsx | 198 ++++++++++++++++++ src/Pages/question/Model/Add.tsx | 5 - src/Pages/question/Model/AddModel.tsx | 76 ------- src/Pages/question/Model/Edit.tsx | 1 - src/Pages/question/Model/EditModel.tsx | 86 -------- src/Pages/question/Model/Malty/Add.tsx | 121 +++++++++++ .../Model/Malty/ChoiceField/CheckboxField.tsx | 37 ++++ .../Model/Malty/ChoiceField/ChoiceFields.tsx | 28 +++ .../question/Model/Malty/ChoiceField/File.tsx | 86 ++++++++ .../Model/Malty/ChoiceField/TextField.tsx | 72 +++++++ src/Pages/question/Model/Malty/Edit.tsx | 121 +++++++++++ .../Model/Malty/QuestionFIeld/File.tsx | 85 ++++++++ .../Malty/QuestionFIeld/QuestionFIeld.tsx | 25 +++ .../Model/Malty/QuestionFIeld/TextField.tsx | 71 +++++++ .../question/Model/Malty/Tags/DynamicTags.tsx | 107 ++++++++++ src/Pages/question/Model/Malty/Tags/Tag.tsx | 71 +++++++ src/Pages/question/Model/Tags/Tag.tsx | 13 +- src/Pages/question/Model/formUtil.ts | 78 +++++-- src/Pages/question/Table.tsx | 6 +- src/Pages/subject/Model/Add.tsx | 16 +- src/Pages/subject/Model/AddModel.tsx | 3 +- src/Pages/subject/Model/Edit.tsx | 16 +- .../show/Tables/Contents/Model/AddModel.tsx | 2 +- .../show/Tables/Contents/Model/EditModel.tsx | 2 +- src/Routes.tsx | 8 +- src/Styles/Pages/exercise.scss | 10 + src/api/config.ts | 4 +- src/translate/ar.json | 11 +- src/types/Auth.ts | 3 - src/types/Item.ts | 2 + src/zustand/AuthState.ts | 2 +- src/zustand/ObjectToEditState.ts | 9 +- 49 files changed, 1328 insertions(+), 289 deletions(-) create mode 100644 src/Components/exercise/Header.tsx create mode 100644 src/Pages/question/AddPage.tsx create mode 100644 src/Pages/question/EditPage.tsx delete mode 100644 src/Pages/question/Model/AddModel.tsx delete mode 100644 src/Pages/question/Model/EditModel.tsx create mode 100644 src/Pages/question/Model/Malty/Add.tsx create mode 100644 src/Pages/question/Model/Malty/ChoiceField/CheckboxField.tsx create mode 100644 src/Pages/question/Model/Malty/ChoiceField/ChoiceFields.tsx create mode 100644 src/Pages/question/Model/Malty/ChoiceField/File.tsx create mode 100644 src/Pages/question/Model/Malty/ChoiceField/TextField.tsx create mode 100644 src/Pages/question/Model/Malty/Edit.tsx create mode 100644 src/Pages/question/Model/Malty/QuestionFIeld/File.tsx create mode 100644 src/Pages/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx create mode 100644 src/Pages/question/Model/Malty/QuestionFIeld/TextField.tsx create mode 100644 src/Pages/question/Model/Malty/Tags/DynamicTags.tsx create mode 100644 src/Pages/question/Model/Malty/Tags/Tag.tsx diff --git a/src/Components/ValidationField/View/Default.tsx b/src/Components/ValidationField/View/Default.tsx index 79753d3..8e5f561 100644 --- a/src/Components/ValidationField/View/Default.tsx +++ b/src/Components/ValidationField/View/Default.tsx @@ -14,13 +14,20 @@ const Default = ({ type, no_label, label_icon, + label2, ...props }: ValidationFieldPropsInput) => { const { errorMsg, isError, t } = useFormField(name, props); return (
- {no_label ? ( + {label2 ? ( + + ) + + :no_label ? ( diff --git a/src/Components/ValidationField/utils/types.ts b/src/Components/ValidationField/utils/types.ts index 5535241..f2e2003 100644 --- a/src/Components/ValidationField/utils/types.ts +++ b/src/Components/ValidationField/utils/types.ts @@ -182,6 +182,7 @@ export interface ValidationFieldPropsInput isDisabled?:boolean no_label?:string label_icon?:string +label2?:string } diff --git a/src/Components/exercise/Header.tsx b/src/Components/exercise/Header.tsx new file mode 100644 index 0000000..60c2876 --- /dev/null +++ b/src/Components/exercise/Header.tsx @@ -0,0 +1,38 @@ +import { useFormikContext } from 'formik'; +import React from 'react'; +import { useTranslation } from 'react-i18next'; +import { GoArrowSwitch } from 'react-icons/go'; +import { useObjectToEdit } from '../../zustand/ObjectToEditState'; + +const Header = () => { + const [t] = useTranslation(); + const { values, setFieldValue,setValues } = useFormikContext(); + const {isBseQuestion,set_isBseQuestion} = useObjectToEdit() + + const handleChange = () => { + + if (isBseQuestion) { + set_isBseQuestion(false) + setValues(null) + + } else { + + set_isBseQuestion(true) + setValues(null) + } + }; + + return ( +
+
+ {t("practical.add")} {t("models.exercise")}{" "} +
+
+ + {isBseQuestion ? t("header.malty_exercise") :t("header.exercise") } +
+
+ ); +}; + +export default Header; diff --git a/src/Pages/Auth/LoginForm.tsx b/src/Pages/Auth/LoginForm.tsx index fa354fd..e1ac712 100644 --- a/src/Pages/Auth/LoginForm.tsx +++ b/src/Pages/Auth/LoginForm.tsx @@ -14,7 +14,7 @@ const LoginForm = () => { const [t] = useTranslation(); const handelSubmit = (values: FormValues) => { - mutate(values ); + mutate(values); }; const { login } = useAuthState(); diff --git a/src/Pages/Auth/formutils.ts b/src/Pages/Auth/formutils.ts index b1ae058..bd6faa1 100644 --- a/src/Pages/Auth/formutils.ts +++ b/src/Pages/Auth/formutils.ts @@ -4,15 +4,9 @@ import { FormValues } from "../../types/Auth"; export const validationSchema = Yup.object().shape({ username: Yup.string().required("Username is required"), password: Yup.string().required("Password is required"), - cycle: Yup.string().required("Cycle is required"), - branch: Yup.string().required("Branch is required"), - term: Yup.string().required("Term is required"), }); export const initialValues: FormValues = { username: null, password: null, - cycle: null, - branch: null, - term: null, }; diff --git a/src/Pages/Unit/Model/AddModel.tsx b/src/Pages/Unit/Model/AddModel.tsx index af7a7e3..5a41c6b 100644 --- a/src/Pages/Unit/Model/AddModel.tsx +++ b/src/Pages/Unit/Model/AddModel.tsx @@ -38,7 +38,7 @@ const ModalForm: React.FC = () => { { - - - ); }; diff --git a/src/Pages/Unit/Model/EditModel.tsx b/src/Pages/Unit/Model/EditModel.tsx index 8105e4d..11a77e0 100644 --- a/src/Pages/Unit/Model/EditModel.tsx +++ b/src/Pages/Unit/Model/EditModel.tsx @@ -43,7 +43,7 @@ const ModalForm: React.FC = () => { { - - - ); }; diff --git a/src/Pages/Unit/Model/formUtil.ts b/src/Pages/Unit/Model/formUtil.ts index d411d79..365816f 100644 --- a/src/Pages/Unit/Model/formUtil.ts +++ b/src/Pages/Unit/Model/formUtil.ts @@ -4,8 +4,6 @@ export const getInitialValues = (objectToEdit: any): any => { return { id: objectToEdit?.id, name: objectToEdit?.name ?? "", - // subject_id:objectToEdit?.subject_id??null, - term: objectToEdit?.term ?? null, }; }; @@ -14,6 +12,5 @@ export const getValidationSchema = () => { return Yup.object().shape({ name: Yup.string().required("validation.required"), // subject_id: Yup.string().required('validation.required'), - term: Yup.string().required("validation.required"), }); }; diff --git a/src/Pages/Unit/useTableColumns.tsx b/src/Pages/Unit/useTableColumns.tsx index 0af4eaf..d049c5a 100644 --- a/src/Pages/Unit/useTableColumns.tsx +++ b/src/Pages/Unit/useTableColumns.tsx @@ -69,20 +69,12 @@ export const useColumns = () => { render: (text, record) => record?.name, }, - { - title: t("columns.term"), - dataIndex: "term", - key: "term", - align: "center", - render: (text, record) => record?.term, - }, - { title: t("columns.lesson_count"), dataIndex: "lesson_count", key: "lesson_count", align: "center", - render: (text, record) => record?.lessons?.length, + render: (text, record) => record?.lessons_count, }, { diff --git a/src/Pages/lesson/Model/Add.tsx b/src/Pages/lesson/Model/Add.tsx index 8236946..6337d8c 100644 --- a/src/Pages/lesson/Model/Add.tsx +++ b/src/Pages/lesson/Model/Add.tsx @@ -20,7 +20,7 @@ const Form = () => { - + ); }; diff --git a/src/Pages/lesson/Model/AddModel.tsx b/src/Pages/lesson/Model/AddModel.tsx index 98b5de5..3a1db52 100644 --- a/src/Pages/lesson/Model/AddModel.tsx +++ b/src/Pages/lesson/Model/AddModel.tsx @@ -42,7 +42,7 @@ const ModalForm: React.FC = () => { { - + ); }; diff --git a/src/Pages/lesson/Model/EditModel.tsx b/src/Pages/lesson/Model/EditModel.tsx index f66ee08..95cfd27 100644 --- a/src/Pages/lesson/Model/EditModel.tsx +++ b/src/Pages/lesson/Model/EditModel.tsx @@ -46,7 +46,7 @@ const ModalForm: React.FC = () => { { align: "center", render: (text, record) => record?.name, }, - - { - title: t("columns.description"), - dataIndex: "description", - key: "description", - align: "center", - render: (text, record) => record?.description, - }, - { title: can_add_Lesson ? ( +
+ + + + + ); + } + return ( +
+ + + +
+
+
+ +
+
{t("practical.back")}
+ +
+
+
+ +
+ ); +}; + +export default AddPage; diff --git a/src/Pages/question/EditPage.tsx b/src/Pages/question/EditPage.tsx new file mode 100644 index 0000000..38a47a9 --- /dev/null +++ b/src/Pages/question/EditPage.tsx @@ -0,0 +1,198 @@ +import React, { useEffect } from "react"; +import { Modal, Spin } from "antd"; +import FormikForm from "../../Layout/Dashboard/FormikFormModel"; +import { getInitialValues, getValidationSchema ,getInitialValuesBase, getValidationSchemaBase} from "./Model/formUtil"; +import { useAddQuestion, useGetAllQuestion, useUpdateQuestion } from "../../api/Question"; +import { useQueryClient } from "react-query"; +import { useTranslation } from "react-i18next"; +import { useNavigate, useParams } from "react-router-dom"; +import { ParamsEnum } from "../../enums/params"; +import { useObjectToEdit } from "../../zustand/ObjectToEditState"; +import { removeStringKeys } from "../../utils/removeStringKeys"; +import SpinContainer from "../../Components/Layout/SpinContainer"; +import Header from "../../Components/exercise/Header"; +import Form from './Model/Edit' +import BaseForm from './Model/Malty/Edit' +import { Question } from "../../types/Item"; + +const EditPage: React.FC = () => { + + const {question_id,subject_id} = useParams() + const {isBseQuestion,set_isBseQuestion} = useObjectToEdit() + + const { mutate, isSuccess, isLoading } = useUpdateQuestion(); + const { mutate:AddQuestion} = useAddQuestion(); + + const {data,isLoading:dataLoading}= useGetAllQuestion({show:question_id}) + + const {data:Questions,isLoading:QuestionsDataLoading}= useGetAllQuestion({parent_id:question_id}) + + const object_to_edit = {...data?.data,Questions:Questions?.data } ; + + + useEffect(() => { + if(object_to_edit?.isBase === 1 && isBseQuestion !== true){ + set_isBseQuestion(true) + + } + }, [object_to_edit?.isBase]) + + + const handleSubmit = (values: any) => { + const DataToSend = structuredClone(values); + + console.log(isBseQuestion); + + if(isBseQuestion){ + console.log(1); + + const UpdateBseQuestion = { + "id":DataToSend?.id, + "content" : DataToSend?.content, + "image": DataToSend?.image ?? "", + "max_mark" : DataToSend?.max_mark, + "min_mark_to_pass" : DataToSend?.min_mark_to_pass, + } + if( typeof UpdateBseQuestion?.image === "string"){ + delete UpdateBseQuestion["image"] + } + + mutate(UpdateBseQuestion) + const Questions = DataToSend?.Questions; + + Questions?.map((item:Question)=>{ + const itemToSend = structuredClone(item); + const keysToRemove = ['image', 'answer_image']; + const updatedObject = removeStringKeys(itemToSend, keysToRemove); + console.log(updatedObject,"updatedObject"); + if(updatedObject?.id){ + mutate({ + ...updatedObject, + + }) + }else{ + AddQuestion({ + ...updatedObject, + parent_id:UpdateBseQuestion?.id, + subject_id:subject_id + + }) + } + + + }) + }else{ + console.log(2); + + const keysToRemove = ['image', 'answer_image']; + const updatedObject = removeStringKeys(DataToSend, keysToRemove); + mutate({ ...updatedObject }); + } + }; + + const navigate = useNavigate() + const handleCancel = () => { + navigate(-1) + }; + + const [t] = useTranslation(); + + useEffect(() => { + if(isSuccess){ + navigate(-1) + } + }, [isSuccess]) + + + console.log(object_to_edit); + + console.log(object_to_edit?.isBase && object_to_edit?.isBase === 0); + + + if(dataLoading && !!(object_to_edit?.isBase) && QuestionsDataLoading){ + return + } + if(object_to_edit?.isBase === 1){ + + + return ( +
+ + + +
+ {/*
*/} +
+
+ {t("practical.edit")} {t("models.exercise")}{" "} +
+
+ + {t("header.exercise") } +
+
+ +
+
{t("practical.back")}
+ +
+
+
+ +
+ ); + } + + return ( +
+ + + +
+ {/*
*/} +
+
+ {t("practical.edit")} {t("models.exercise")}{" "} +
+
+ + {t("header.exercise") } +
+
+ +
+
{t("practical.back")}
+ +
+
+
+ +
+ ); +}; + +export default EditPage; diff --git a/src/Pages/question/Model/Add.tsx b/src/Pages/question/Model/Add.tsx index 7b2a9bc..0882d15 100644 --- a/src/Pages/question/Model/Add.tsx +++ b/src/Pages/question/Model/Add.tsx @@ -44,17 +44,12 @@ const Form = () => { - {/* */}
-
- {/* */} - - {/* */}
{ diff --git a/src/Pages/question/Model/AddModel.tsx b/src/Pages/question/Model/AddModel.tsx deleted file mode 100644 index 0f867da..0000000 --- a/src/Pages/question/Model/AddModel.tsx +++ /dev/null @@ -1,76 +0,0 @@ -import React, { useEffect } from "react"; -import { Modal, Spin } from "antd"; -import FormikForm from "../../../Layout/Dashboard/FormikFormModel"; -import ModelBody from "./Add"; -import { getInitialValues, getValidationSchema } from "./formUtil"; -import { useAddQuestion } from "../../../api/Question"; -import { useQueryClient } from "react-query"; -import { useTranslation } from "react-i18next"; -import { useNavigate, useParams } from "react-router-dom"; -import { ParamsEnum } from "../../../enums/params"; -import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; - -const ModalForm: React.FC = () => { - - const queryClient = useQueryClient(); - - const { mutate, isSuccess, isLoading } = useAddQuestion(); - const {object_to_edit} = useObjectToEdit() - - const {subject_id} = useParams() - - - const handleSubmit = (values: any) => { - console.log(values,"values"); - - mutate({ ...values, subject_id:subject_id }); - }; - const navigate = useNavigate() - useEffect(() => { - if(isSuccess){ - navigate(-1) - - } - }, [isSuccess]) - - const handleCancel = () => { - navigate(-1) - }; - - const [t] = useTranslation(); - - return ( -
- - - -
-
- {" "} - {t("practical.add")} {t("models.exercise")}{" "} -
- -
-
{t("practical.back")}
- -
-
-
- -
- ); -}; - -export default ModalForm; diff --git a/src/Pages/question/Model/Edit.tsx b/src/Pages/question/Model/Edit.tsx index acd5247..dba5338 100644 --- a/src/Pages/question/Model/Edit.tsx +++ b/src/Pages/question/Model/Edit.tsx @@ -46,7 +46,6 @@ const Form = () => { {/* */}
-
diff --git a/src/Pages/question/Model/EditModel.tsx b/src/Pages/question/Model/EditModel.tsx deleted file mode 100644 index e5f8b8f..0000000 --- a/src/Pages/question/Model/EditModel.tsx +++ /dev/null @@ -1,86 +0,0 @@ -import React, { useEffect } from "react"; -import { Modal, Spin } from "antd"; -import FormikForm from "../../../Layout/Dashboard/FormikFormModel"; -import ModelBody from "./Add"; -import { getInitialValues, getValidationSchema } from "./formUtil"; -import { useGetAllQuestion, useUpdateQuestion } from "../../../api/Question"; -import { useQueryClient } from "react-query"; -import { useTranslation } from "react-i18next"; -import { useNavigate, useParams } from "react-router-dom"; -import { ParamsEnum } from "../../../enums/params"; -import { useObjectToEdit } from "../../../zustand/ObjectToEditState"; -import { removeStringKeys } from "../../../utils/removeStringKeys"; -import SpinContainer from "../../../Components/Layout/SpinContainer"; - -const ModalForm: React.FC = () => { - - const {question_id,subject_id} = useParams() - - const { mutate, isSuccess, isLoading } = useUpdateQuestion(); - const {data,isLoading:dataLoading}= useGetAllQuestion({show:question_id}) - - const object_to_edit = data?.data ; - - const handleSubmit = (values: any) => { - console.log(values, "values"); - const DataToSend = structuredClone(values); - - const keysToRemove = ['image', 'answer_image']; - const updatedObject = removeStringKeys(DataToSend, keysToRemove); - - mutate({ ...updatedObject }); - }; - - const navigate = useNavigate() - const handleCancel = () => { - navigate(-1) - }; - - const [t] = useTranslation(); - - useEffect(() => { - if(isSuccess){ - navigate(-1) - } - }, [isSuccess]) - - - if(dataLoading){ - return - } - - return ( -
- - - -
-
- {" "} - {t("practical.edit")} {t("models.exercise")}{" "} -
- -
-
{t("practical.back")}
- -
-
-
- -
- ); -}; - -export default ModalForm; diff --git a/src/Pages/question/Model/Malty/Add.tsx b/src/Pages/question/Model/Malty/Add.tsx new file mode 100644 index 0000000..673f784 --- /dev/null +++ b/src/Pages/question/Model/Malty/Add.tsx @@ -0,0 +1,121 @@ + 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 PdfUploader from "../../../../Components/CustomFields/PdfUploader"; +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 { useGetAllQuestion } from "../../../../api/Question"; +import QuestionFIeld from "./QuestionFIeld/QuestionFIeld"; + +const Form = () => { + const formik = useFormikContext(); + const { isOpen } = useModalState((state) => state); + // const {data} = useGetAllQuestion(); + + useEffect(() => { + if (isOpen === "") { + formik.setErrors({}); + formik.resetForm(); + } + }, [isOpen]); + + // console.log(formik?.errors); + + + const handleAddChoice = (parent_index:number) => { + console.log(parent_index); + + formik.setFieldValue(`Questions.[${parent_index}].QuestionOptions`, [...(formik?.values as any)?.Questions?.[parent_index].QuestionOptions 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, + QuestionOptions: [{ 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() + console.log(formik.errors); + + + return ( + +
+ + + + +
+ + + +
+
+ +
+ +
+
+ +
+ + { + (((formik?.values as any)?.Questions as Choice[])||[]) .map((item:Choice,parent_index:number)=>{ + + return ( +
+ +
+ +
+ + { + (((formik?.values as any)?.Questions?.[parent_index]?.QuestionOptions as Choice[])||[]) .map((item:Choice,index:number)=>{ + + return + } + ) + } +

+ handleAddChoice(parent_index)} size={23} /> {t("header.add_new_choice")} +

+ + +
+ ) + } + ) + } + +

+ {t("header.add_new_question")} +

+
+ ); +}; + +export default Form; diff --git a/src/Pages/question/Model/Malty/ChoiceField/CheckboxField.tsx b/src/Pages/question/Model/Malty/ChoiceField/CheckboxField.tsx new file mode 100644 index 0000000..630ecb6 --- /dev/null +++ b/src/Pages/question/Model/Malty/ChoiceField/CheckboxField.tsx @@ -0,0 +1,37 @@ +import React from "react"; +import useFormField from "../../../../../Hooks/useFormField"; +import { Checkbox, Form } from "antd"; +import { useFormik, useFormikContext } from "formik"; +import { useTranslation } from "react-i18next"; +const CheckboxField = ({ + name, + label, + isDisabled, + onChange, + Group, + className, + parent_index, + props, +}: any) => { + const formik = useFormikContext() + const [t] = useTranslation() + const CheckboxhandleChange = (value: any) => { + console.log(value?.target?.checked); + + formik.setFieldValue(`Questions[${parent_index}].QuestionOptions[${name}].isCorrect`, value?.target?.checked ? 1 : 0); + }; + return ( +
+ + {t(`input.${label ? label : name}`)} + +
+ ); +}; + +export default CheckboxField; diff --git a/src/Pages/question/Model/Malty/ChoiceField/ChoiceFields.tsx b/src/Pages/question/Model/Malty/ChoiceField/ChoiceFields.tsx new file mode 100644 index 0000000..426850e --- /dev/null +++ b/src/Pages/question/Model/Malty/ChoiceField/ChoiceFields.tsx @@ -0,0 +1,28 @@ +import React from 'react' +import { Choice } from '../../../../../types/Item' +import ValidationField from '../../../../../Components/ValidationField/ValidationField' +import { useFormikContext } from 'formik'; +import { useTranslation } from 'react-i18next'; +import { getCharFromNumber } from '../../../../../utils/getCharFromNumber'; +import CheckboxField from './CheckboxField'; +import TextField from './TextField'; +import File from './File'; + +const ChoiceFields = ({index,parent_index,data}:{index:number ,parent_index:number, data :Choice }) => { + const formik = useFormikContext(); + + const [t] = useTranslation() + return ( +
+ + + + + + + +
+ ) +} + +export default ChoiceFields \ No newline at end of file diff --git a/src/Pages/question/Model/Malty/ChoiceField/File.tsx b/src/Pages/question/Model/Malty/ChoiceField/File.tsx new file mode 100644 index 0000000..f5d4c88 --- /dev/null +++ b/src/Pages/question/Model/Malty/ChoiceField/File.tsx @@ -0,0 +1,86 @@ +import { Button, Upload, UploadFile } from "antd"; +import useFormField from "../../../../../Hooks/useFormField"; +import { UploadOutlined } from "@ant-design/icons"; +import { useMemo } from "react"; + +const File = ({ + name, + label, + onChange, + isDisabled, + placholder, + className, + parent_index, + props, +}: any) => { + + const newName = `Questions[${parent_index}].QuestionOptions[${name}].answer_image` + + const { formik, t, isError,errorMsg } = useFormField(newName, props); + let imageUrl = formik?.values?.Questions?.[parent_index]?.QuestionOptions[name]?.answer_image ?? null; + // console.log(imageUrl); + + const fileList: UploadFile[] = useMemo(() => { + if (!imageUrl) return []; + + return [ + typeof imageUrl === 'string' + ? { + uid: '-1', + name: 'uploaded-image', + status: 'done', + url: imageUrl, + thumbUrl: imageUrl, + } + : { + uid: imageUrl.uid || '-1', + name: imageUrl.name || 'uploaded-image', + status: 'done', + originFileObj: imageUrl, + }, + ]; + }, [imageUrl]); + // console.log(1); + + const FilehandleChange = (value: any) => { + // console.log(value,"filevalue"); + if (value.fileList.length === 0) { + formik.setFieldValue(newName, null); + } else { + formik.setFieldValue(`Questions[${parent_index}].QuestionOptions[${name}].answer_image`, value?.file?.originFileObj); + + } + }; + const customRequest = async ({ onSuccess, no_label, label_icon }: any) => { + onSuccess(); + }; + return ( +
+ + + + +
{isError ? "required" : ""}
+ {errorMsg} +
+
+ ); +}; + +export default File; diff --git a/src/Pages/question/Model/Malty/ChoiceField/TextField.tsx b/src/Pages/question/Model/Malty/ChoiceField/TextField.tsx new file mode 100644 index 0000000..b65fdd8 --- /dev/null +++ b/src/Pages/question/Model/Malty/ChoiceField/TextField.tsx @@ -0,0 +1,72 @@ +import { Form, Input } from "antd"; +import React from "react"; +import useFormField from "../../../../../Hooks/useFormField"; +import { MdOutlineEdit } from "react-icons/md"; +import { Field } from "formik"; +const { TextArea } = Input; + +const TextField = ({ + name, + label, + label2, + placeholder, + isDisabled, + onChange, + props, + no_label, + label_icon, + parent_index, + className +}: any) => { + const newName = `Questions[${parent_index}].QuestionOptions[${name}].answer` + const { formik, isError, errorMsg, t } = useFormField(newName, props); + const TextFilehandleChange = ( + e: React.ChangeEvent, + ) => { + // console.log('Change:', e.target.value); + formik.setFieldValue(newName, e.target.value); + }; + + return ( +
+ {no_label ? ( + + ) : label_icon ? ( +
+ + +
+ ) : ( + + )} + + + + +
+ ); +}; + +export default React.memo(TextField); diff --git a/src/Pages/question/Model/Malty/Edit.tsx b/src/Pages/question/Model/Malty/Edit.tsx new file mode 100644 index 0000000..d7a1359 --- /dev/null +++ b/src/Pages/question/Model/Malty/Edit.tsx @@ -0,0 +1,121 @@ +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 PdfUploader from "../../../../Components/CustomFields/PdfUploader"; +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 { useGetAllQuestion } from "../../../../api/Question"; +import QuestionFIeld from "./QuestionFIeld/QuestionFIeld"; + +const Form = () => { + const formik = useFormikContext(); + const { isOpen } = useModalState((state) => state); + // const {data} = useGetAllQuestion(); + + useEffect(() => { + if (isOpen === "") { + formik.setErrors({}); + formik.resetForm(); + } + }, [isOpen]); + + // console.log(formik?.errors); + const [t] = useTranslation() + + + const handleAddChoice = (parent_index:number) => { + console.log(parent_index); + + formik.setFieldValue(`Questions.[${parent_index}].QuestionOptions`, [...(formik?.values as any)?.Questions?.[parent_index].QuestionOptions, + + { + answer:null, + answer_image:null, + isCorrect:0 + }]) + } + + + const handleAddQuestion = () => { + formik.setFieldValue('Questions', [...(formik?.values as any)?.Questions, + + { + content: "", + image: "", + parent: '', + isBase: 0, + max_mark: 1, + min_mark_to_pass: 1, + QuestionOptions: [{ answer: null, answer_image: null, isCorrect: 0 }], + tags: [] + }]) + + const max_mark = formik?.values?.max_mark + 1 + + formik.setFieldValue('max_mark', max_mark) + } + console.log(formik?.values); + + return ( + +
+ + + + +
+ + + +
+
+ +
+ +
+
+ +
+ + { + (((formik?.values as any)?.Questions)||[])?.map((item:Choice,parent_index:number)=>{ + + return ( +
+ +
+ + +
+ + { + (((formik?.values as any)?.Questions?.[parent_index]?.QuestionOptions)||[]) .map((item:Choice,index:number)=>{ + + return + } + ) + } +

+ handleAddChoice(parent_index)} size={23} /> {t("header.add_new_choice")} +

+ + +
+ ) + } + ) + } + +

+ {t("header.add_new_question")} +

+
+ ); +}; + +export default Form; diff --git a/src/Pages/question/Model/Malty/QuestionFIeld/File.tsx b/src/Pages/question/Model/Malty/QuestionFIeld/File.tsx new file mode 100644 index 0000000..457e1a5 --- /dev/null +++ b/src/Pages/question/Model/Malty/QuestionFIeld/File.tsx @@ -0,0 +1,85 @@ +import { Button, Upload, UploadFile } from "antd"; +import useFormField from "../../../../../Hooks/useFormField"; +import { UploadOutlined } from "@ant-design/icons"; +import { useMemo } from "react"; + +const File = ({ + name, + label, + onChange, + isDisabled, + placholder, + className, + props, +}: any) => { + + const newName = `Questions[${name}].image` + + const { formik, t, isError,errorMsg } = useFormField(newName, props); + let imageUrl = formik?.values?.Questions?.[name]?.image ?? null; + // console.log(imageUrl); + + const fileList: UploadFile[] = useMemo(() => { + if (!imageUrl) return []; + + return [ + typeof imageUrl === 'string' + ? { + uid: '-1', + name: 'uploaded-image', + status: 'done', + url: imageUrl, + thumbUrl: imageUrl, + } + : { + uid: imageUrl.uid || '-1', + name: imageUrl.name || 'uploaded-image', + status: 'done', + originFileObj: imageUrl, + }, + ]; + }, [imageUrl]); + // console.log(1); + + const FilehandleChange = (value: any) => { + // console.log(value,"filevalue"); + if (value.fileList.length === 0) { + formik.setFieldValue(newName, null); + } else { + formik.setFieldValue(`Questions[${name}].image`, value?.file?.originFileObj); + + } + }; + const customRequest = async ({ onSuccess, no_label, label_icon }: any) => { + onSuccess(); + }; + return ( +
+ + + + +
{isError ? "required" : ""}
+ {errorMsg} +
+
+ ); +}; + +export default File; diff --git a/src/Pages/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx b/src/Pages/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx new file mode 100644 index 0000000..47ec2f1 --- /dev/null +++ b/src/Pages/question/Model/Malty/QuestionFIeld/QuestionFIeld.tsx @@ -0,0 +1,25 @@ +import React from 'react' +import { Choice } from '../../../../../types/Item' +import ValidationField from '../../../../../Components/ValidationField/ValidationField' +import { useFormikContext } from 'formik'; +import { useTranslation } from 'react-i18next'; +import { getCharFromNumber } from '../../../../../utils/getCharFromNumber'; +import TextField from './TextField'; +import File from './File'; + +const QuestionFIeld = ({index,data}:{index:number , data :Choice }) => { + const formik = useFormikContext(); + console.log(index); + + const [t] = useTranslation() + return ( +
+ + + + +
+ ) +} + +export default QuestionFIeld \ No newline at end of file diff --git a/src/Pages/question/Model/Malty/QuestionFIeld/TextField.tsx b/src/Pages/question/Model/Malty/QuestionFIeld/TextField.tsx new file mode 100644 index 0000000..db669f2 --- /dev/null +++ b/src/Pages/question/Model/Malty/QuestionFIeld/TextField.tsx @@ -0,0 +1,71 @@ +import { Form, Input } from "antd"; +import React from "react"; +import useFormField from "../../../../../Hooks/useFormField"; +import { MdOutlineEdit } from "react-icons/md"; +import { Field } from "formik"; +const { TextArea } = Input; + +const TextField = ({ + name, + label, + label2, + placeholder, + isDisabled, + onChange, + props, + no_label, + label_icon, + className +}: any) => { + const newName = `Questions[${name}].content` + const { formik, isError, errorMsg, t } = useFormField(newName, props); + const TextFilehandleChange = ( + e: React.ChangeEvent, + ) => { + // console.log('Change:', e.target.value); + formik.setFieldValue(newName, e.target.value); + }; + + return ( +
+ {no_label ? ( + + ) : label_icon ? ( +
+ + +
+ ) : ( + + )} + + + + +
+ ); +}; + +export default React.memo(TextField); diff --git a/src/Pages/question/Model/Malty/Tags/DynamicTags.tsx b/src/Pages/question/Model/Malty/Tags/DynamicTags.tsx new file mode 100644 index 0000000..375fe4c --- /dev/null +++ b/src/Pages/question/Model/Malty/Tags/DynamicTags.tsx @@ -0,0 +1,107 @@ +import { useFormikContext } from 'formik' +import React from 'react' +import { useTranslation } from 'react-i18next' +import { FaCirclePlus } from 'react-icons/fa6' +import Tag from './Tag' +import { useObjectToEdit } from '../../../../../zustand/ObjectToEditState' +import { useGetAllTag } from '../../../../../api/tags' + +const DynamicTags = ({parent_index}:{parent_index:number}) => { + + const formik = useFormikContext() + const [t] = useTranslation() + const { Tags_search ,set_Tags_search,currentTag,current_parent_index} = useObjectToEdit(); + const {data} = useGetAllTag({ + name : Tags_search + }) + const suggests = data?.data + + + const handleAddChoice = () => { + const length = formik?.values?.Questions?.[parent_index]?.tags.length; + const lastElement = formik?.values?.Questions?.[parent_index]?.tags[length - 1]?.name; + + if(lastElement !== ""){ + formik.setFieldValue(`Questions.[${parent_index}].tags`, [...(formik?.values as any)?.Questions?.[parent_index]?.tags as any[], + + { + id:length +"_new", + name:"", + key:length + }]) + }else{ + + } + + +} +// console.log(formik?.values); +// console.log(currentTag); + +const handleChoice = (item: any) => { + + const length = formik.values.tags.length; + console.log(currentTag); + + formik.setFieldValue(`Questions.[${parent_index}].tags[${currentTag}]`, {...item,key:length}); + set_Tags_search(null); +} + + + +// console.log(formik?.values?.tags?.length); + + return ( +
+ {formik?.values?.tags?.length < 1 && + +

+ {t("header.add_tag")} +

+ } + +
+
+ +{ +(((formik?.values as any)?.Questions?.[parent_index]?.tags as any[])||[]) .map((item:any,index:number)=>{ + +return ( + + + +) +} +) +} +
+ + {formik?.values?.Questions?.[parent_index]?.tags?.length > 0 && + +

+ +

+ + } + +
+ {Tags_search && current_parent_index === parent_index && +
+ {suggests?.map((item:any,index:number)=>{ + console.log(current_parent_index === parent_index); + + return ( +
handleChoice(item)}> + {item?.name} +
+ ) + })} +
+ } + + +
+ ) +} + +export default DynamicTags \ No newline at end of file diff --git a/src/Pages/question/Model/Malty/Tags/Tag.tsx b/src/Pages/question/Model/Malty/Tags/Tag.tsx new file mode 100644 index 0000000..09ed75f --- /dev/null +++ b/src/Pages/question/Model/Malty/Tags/Tag.tsx @@ -0,0 +1,71 @@ +import { useFormikContext } from 'formik'; +import React, { useRef, useEffect } from 'react'; +import { useObjectToEdit } from '../../../../../zustand/ObjectToEditState'; +import { FaTrash } from 'react-icons/fa'; + +const Tag = ({ data, index,parent_index }: { data: any, index: number,parent_index:number }) => { + const inputRef = useRef(null); + const timeoutRef = useRef(null); + const DEBOUNCE_DELAY = 500; + const formik = useFormikContext(); + const { set_Tags_search ,set_currentTag,set_current_parent_index} = useObjectToEdit(); + + useEffect(() => { + if (inputRef.current) { + inputRef.current.style.width = `${(formik?.values?.Questions?.[parent_index]?.tags[index]?.name?.length + 1) * 8}px`; + } + }, [formik?.values?.Questions?.[parent_index]?.tags[index]?.name]); + + const handleEditInputChange = (e: React.ChangeEvent) => { + // console.log(e.target.value); + formik.setFieldValue(`Questions.[${parent_index}].tags[${index}].name`, e.target.value); + set_currentTag(index) + set_current_parent_index(parent_index) + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + } + + timeoutRef.current = setTimeout(() => { + set_Tags_search(e.target.value) + }, DEBOUNCE_DELAY); + }; + + const handleDeleteChoice = () => { + console.log(data); + + // Create a copy of current tags array + const currentTags = [...formik.values.tags]; + + // Remove the item at the specified index from the array + currentTags.splice(index, 1); + + console.log(currentTags); // Log the updated tags array + + // Update formik field value with the updated tags array + formik.setFieldValue(`Questions.[${parent_index}].tags`, currentTags); + + // Reset search state if needed + set_Tags_search(null); + }; + + + + return ( +
+ + +
+ ); +}; + +export default Tag; + + + diff --git a/src/Pages/question/Model/Tags/Tag.tsx b/src/Pages/question/Model/Tags/Tag.tsx index 70e87bb..09de022 100644 --- a/src/Pages/question/Model/Tags/Tag.tsx +++ b/src/Pages/question/Model/Tags/Tag.tsx @@ -7,7 +7,8 @@ const Tag = ({ data, index }: { data: any, index: number }) => { const inputRef = useRef(null); const formik = useFormikContext(); const { set_Tags_search ,set_currentTag} = useObjectToEdit(); - + const timeoutRef = useRef(null); + const DEBOUNCE_DELAY = 500; useEffect(() => { if (inputRef.current) { inputRef.current.style.width = `${(formik?.values?.tags[index]?.name?.length + 1) * 8}px`; @@ -17,9 +18,15 @@ const Tag = ({ data, index }: { data: any, index: number }) => { const handleEditInputChange = (e: React.ChangeEvent) => { // console.log(e.target.value); formik.setFieldValue(`tags[${index}].name`, e.target.value); - set_Tags_search(e.target.value) + // set_Tags_search(e.target.value) set_currentTag(index) - + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + } + + timeoutRef.current = setTimeout(() => { + set_Tags_search(e.target.value) + }, DEBOUNCE_DELAY); }; const handleInputBlur = () => { diff --git a/src/Pages/question/Model/formUtil.ts b/src/Pages/question/Model/formUtil.ts index cc833d2..3afca5c 100644 --- a/src/Pages/question/Model/formUtil.ts +++ b/src/Pages/question/Model/formUtil.ts @@ -3,26 +3,24 @@ import { Question } from "../../../types/Item"; export const getInitialValues = (objectToEdit: Question): any => { - const tags = objectToEdit?.tags?.map((item:any,index:number)=>{ - return {...item,key:index} -}); - console.log(objectToEdit,"objectToEdit"); + const tags = objectToEdit?.tags?.map((item: any, index: number) => { + return { ...item, key: index } + }); return { id: objectToEdit?.id ?? null, content: objectToEdit?.content ?? "", image: objectToEdit?.image ?? "", - subject_id:objectToEdit?.subject_id??'', - isBase:objectToEdit?.isBase??'', - max_mark:objectToEdit?.max_mark??null, - min_mark_to_pass:1, - parent:objectToEdit?.parent??'', - QuestionOptions: objectToEdit?.QuestionOptions ?? [{answer:null,answer_image:null,isCorrect:0}], - tags : tags ??[] + subject_id: objectToEdit?.subject_id ?? '', + isBase: objectToEdit?.isBase, + max_mark: 1, + min_mark_to_pass: 1, + parent: objectToEdit?.parent ?? '', + QuestionOptions: objectToEdit?.QuestionOptions ?? [], + tags: tags ?? [], }; }; - export const getValidationSchema = () => { // validate input return Yup.object().shape({ @@ -30,13 +28,63 @@ export const getValidationSchema = () => { content: Yup.string().required("validation.required"), max_mark: Yup.number().required("validation.required").min(Yup.ref("min_mark_to_pass"),"validation.max_mark_must_be_greater_than_min_mark_to_pass"), min_mark_to_pass: Yup.number().required("validation.required"), - QuestionOptions: Yup.array().of( Yup.object().shape({ - answer: Yup.string().required('details name is required'), + answer: Yup.string().required("validation.required"), answer_image: Yup.string().nullable(), isCorrect: Yup.boolean() }) - ).required('Params are required') + ).nullable('Params are required') + }); +}; + + + +export const getInitialValuesBase = (objectToEdit: Question): any => { + const tags = objectToEdit?.tags?.map((item: any, index: number) => { + return { ...item, key: index } + }); + console.log(objectToEdit); + + const questions = objectToEdit?.Questions ?? []; + + + return { + id: objectToEdit?.id ?? null, + content: objectToEdit?.content ?? "", + image: objectToEdit?.image ?? "", + subject_id: objectToEdit?.subject_id ?? '', + isBase: objectToEdit?.isBase, + max_mark: questions.length ?? 1, + min_mark_to_pass: 1, + parent: objectToEdit?.parent ?? '', + tags: tags ?? [], + Questions: questions, + }; +}; + +export const getValidationSchemaBase = () => { + // validate input + return Yup.object().shape({ + image: Yup.string().nullable(), + content: Yup.string().required("validation.required"), + max_mark: Yup.number().required("validation.required").min(Yup.ref("min_mark_to_pass"),"validation.max_mark_must_be_greater_than_min_mark_to_pass"), + min_mark_to_pass: Yup.number().required("validation.required"), + Questions: Yup.array().of( + Yup.object().shape({ + image: Yup.string().nullable(), + content: Yup.string().required("validation.required"), + max_mark: Yup.number().required("validation.required").min(Yup.ref("min_mark_to_pass"),"validation.max_mark_must_be_greater_than_min_mark_to_pass"), + min_mark_to_pass: Yup.number().required("validation.required"), + QuestionOptions: Yup.array().of( + Yup.object().shape({ + answer: Yup.string().required("validation.required"), + answer_image: Yup.string().nullable(), + isCorrect: Yup.boolean() + }) + ).nullable('required') + }) + ), + }); }; diff --git a/src/Pages/question/Table.tsx b/src/Pages/question/Table.tsx index b1d3fcb..cd26b77 100644 --- a/src/Pages/question/Table.tsx +++ b/src/Pages/question/Table.tsx @@ -6,10 +6,10 @@ import { useParams } from "react-router-dom"; import { ParamsEnum } from "../../enums/params"; const App: React.FC = () => { - const {unit_id} = useParams() - const response = useGetAllQuestion({ unit_id:unit_id, pagination: true}); + const {subject_id} = useParams() + const response = useGetAllQuestion({ subject_id:subject_id, pagination: true}); - return ; + return ; }; export default App; diff --git a/src/Pages/subject/Model/Add.tsx b/src/Pages/subject/Model/Add.tsx index 963ead1..97e1a52 100644 --- a/src/Pages/subject/Model/Add.tsx +++ b/src/Pages/subject/Model/Add.tsx @@ -8,13 +8,7 @@ import { useModalState } from "../../../zustand/Modal"; import useSearchQuery from "../../../api/utils/useSearchQuery"; const Form = () => { - const [searchQuery] = useSearchQuery("techer_name"); - const { data , isLoading } = useGetAllTeacher({ - name: searchQuery, - - }); - const SelectData = useFormatDataToSelect(data?.data); const { isOpen } = useModalState((state) => state); const formik = useFormikContext(); useEffect(() => { @@ -28,15 +22,7 @@ const Form = () => { - + diff --git a/src/Pages/subject/Model/AddModel.tsx b/src/Pages/subject/Model/AddModel.tsx index 2f5ace1..55266ea 100644 --- a/src/Pages/subject/Model/AddModel.tsx +++ b/src/Pages/subject/Model/AddModel.tsx @@ -12,7 +12,6 @@ import { useTranslation } from "react-i18next"; const ModalForm: React.FC = () => { const { isOpen, setIsOpen } = useModalState((state) => state); - const { course_id } = useParams(); const { mutate, isSuccess, isLoading } = useAddSubject(); const { set_object_to_edit } = useObjectToEdit(); @@ -27,7 +26,7 @@ const ModalForm: React.FC = () => { // console.log(values,"values"); mutate({ ...values, - course_id: course_id, + }); }; diff --git a/src/Pages/subject/Model/Edit.tsx b/src/Pages/subject/Model/Edit.tsx index 7c3d4c0..8edf7a1 100644 --- a/src/Pages/subject/Model/Edit.tsx +++ b/src/Pages/subject/Model/Edit.tsx @@ -8,12 +8,6 @@ import { useFormikContext } from "formik"; import useSearchQuery from "../../../api/utils/useSearchQuery"; const Form = () => { - const [searchQuery] = useSearchQuery("techer_name"); - - const { data , isLoading } = useGetAllTeacher({ - name: searchQuery, - }); - const SelectData = useFormatDataToSelect(data?.data); const { isOpen } = useModalState((state) => state); const formik = useFormikContext(); @@ -27,15 +21,7 @@ const Form = () => { - + diff --git a/src/Pages/subject/show/Tables/Contents/Model/AddModel.tsx b/src/Pages/subject/show/Tables/Contents/Model/AddModel.tsx index f4c94ba..ad0e8d1 100644 --- a/src/Pages/subject/show/Tables/Contents/Model/AddModel.tsx +++ b/src/Pages/subject/show/Tables/Contents/Model/AddModel.tsx @@ -38,7 +38,7 @@ const ModalForm: React.FC = () => { { import("./Pages/Tags/Page")); const Unit = React.lazy(() => import("./Pages/Unit/Page")); const Lesson = React.lazy(() => import("./Pages/lesson/Page")); const Question = React.lazy(() => import('./Pages/question/Page')) -const AddQuestion = React.lazy(() => import('./Pages/question/Model/AddModel')) -const EditQuestion = React.lazy(() => import('./Pages/question/Model/EditModel')) +const AddQuestionPage = React.lazy(() => import('./Pages/question/AddPage')) +const EditQuestionPage = React.lazy(() => import('./Pages/question/EditPage')) // const QuestionChildren = React.lazy(() => import('./Pages/question/children/Page')) @@ -90,14 +90,14 @@ export const CrudRoute: TCrudRoute[] = [ }, { header: "page_header.add_Question", - element: , + element: , path: `/${ABILITIES_ENUM?.SUBJECT}/:${ParamsEnum?.SUBJECT_ID}/${ABILITIES_ENUM?.UNIT}/:${ParamsEnum?.UNIT_ID}/${ABILITIES_ENUM?.LESSON}/:${ParamsEnum?.LESSON_ID}/${ABILITIES_ENUM?.QUESTION}/add`, abilities: ABILITIES_ENUM?.QUESTION, abilities_value: ABILITIES_VALUES_ENUM.INDEX, }, { header: "page_header.edit_Question", - element: , + element: , path: `/${ABILITIES_ENUM?.SUBJECT}/:${ParamsEnum?.SUBJECT_ID}/${ABILITIES_ENUM?.UNIT}/:${ParamsEnum?.UNIT_ID}/${ABILITIES_ENUM?.LESSON}/:${ParamsEnum?.LESSON_ID}/${ABILITIES_ENUM?.QUESTION}/:${ParamsEnum?.QUESTION_ID}`, abilities: ABILITIES_ENUM?.QUESTION, abilities_value: ABILITIES_VALUES_ENUM.INDEX, diff --git a/src/Styles/Pages/exercise.scss b/src/Styles/Pages/exercise.scss index 39adbe7..1c3b1d0 100644 --- a/src/Styles/Pages/exercise.scss +++ b/src/Styles/Pages/exercise.scss @@ -107,4 +107,14 @@ } +} + +.exercise_add_header{ + display: flex; + justify-content: space-between; + width: 90%; +} + +.inputSmall{ + width: 100px; } \ No newline at end of file diff --git a/src/api/config.ts b/src/api/config.ts index 9c2df36..0b90ec0 100644 --- a/src/api/config.ts +++ b/src/api/config.ts @@ -1,4 +1,6 @@ -export const BaseURL = "http://192.168.1.108:8000/api/"; +// export const BaseURL = "http://192.168.1.108:8000/api/"; +export const BaseURL = "http://127.0.0.1:8000/api/"; + // export const BaseURL = "https://school-back-dev.point-dev.net/api/"; export const ImageBaseURL = "http://192.168.1.9:8000/"; diff --git a/src/translate/ar.json b/src/translate/ar.json index 9e5863b..2ec741b 100644 --- a/src/translate/ar.json +++ b/src/translate/ar.json @@ -99,10 +99,13 @@ "change_your_current_password": "تغير كلمة السر الحالية", "view_cycle_for_this_branch": "مشاهدة الدورات في هذا الفرع", "view_term_for_this_cycle": "مشاهدة الفصول في هذة السنة دراسية", - "add_new_choice":"إضافة خيار آخر", + "add_new_choice":"إضافة خيار ", "add_tag":"إضافة كلمة مفتاحية", "add_synonyms":"إضافة مرادفات", - "add_Question":"إضافة اسئلة" + "add_Question":"إضافة اسئلة", + "malty_exercise":"تمرين متعدد", + "add_new_question":"اضافة سؤال جديد", + "exercise":"تمارين" }, "columns": { @@ -331,7 +334,9 @@ "exercise":"تمارين", "max_mark":"العلامة الكاملة", "min_mark_to_pass" : "علامة النجاح", - "isBase":"سؤال رئيسي" + "isBase":"سؤال رئيسي", + "main_question":"النص الأساسي ", + "question":"السؤال" }, diff --git a/src/types/Auth.ts b/src/types/Auth.ts index 5fc3359..47deeff 100644 --- a/src/types/Auth.ts +++ b/src/types/Auth.ts @@ -1,7 +1,4 @@ export interface FormValues { username: string | null; password: string | null; - cycle: string | null; - branch: string | null; - term: string | null; } diff --git a/src/types/Item.ts b/src/types/Item.ts index 18c7fab..088f0ae 100644 --- a/src/types/Item.ts +++ b/src/types/Item.ts @@ -34,6 +34,7 @@ export interface Unit { description: string | null; subject_id: number; term: term_type; + lessons_count:number; lessons: Lesson[]; } @@ -313,6 +314,7 @@ export interface Question { max_mark: number; min_mark_to_pass: number; image: string | null; + Questions?:any[] QuestionOptions: QuestionOption[]; tags: tags[]; // Assuming tags are strings, adjust as per actual data type } \ No newline at end of file diff --git a/src/zustand/AuthState.ts b/src/zustand/AuthState.ts index 732572a..d994b5d 100644 --- a/src/zustand/AuthState.ts +++ b/src/zustand/AuthState.ts @@ -21,7 +21,7 @@ const useAuthState = create((set) => { const storedAbilities = localStorage.getItem(ABILITIES_KEY); return { - isAuthenticated: !!storedToken && !!storedAbilities, + isAuthenticated: !!storedToken, token: storedToken, abilities: storedAbilities, diff --git a/src/zustand/ObjectToEditState.ts b/src/zustand/ObjectToEditState.ts index 182801c..ea3461c 100644 --- a/src/zustand/ObjectToEditState.ts +++ b/src/zustand/ObjectToEditState.ts @@ -15,7 +15,10 @@ interface ModelState { set_Tags_query: (data: any) => void; currentTag: any; set_currentTag: (data: any) => void; - + current_parent_index: any; + set_current_parent_index: (data: any) => void; + isBseQuestion: boolean; + set_isBseQuestion: (data: any) => void; } export const useObjectToEdit = create((set) => ({ @@ -33,4 +36,8 @@ export const useObjectToEdit = create((set) => ({ set_Tags_query: (data) => set(() => ({ Tags_query: data })), currentTag: null, set_currentTag: (data) => set(() => ({ currentTag: data })), + current_parent_index: null, + set_current_parent_index: (data) => set(() => ({ current_parent_index: data })), + isBseQuestion: false, + set_isBseQuestion: (data) => set(() => ({ isBseQuestion: data })), }));