This commit is contained in:
Moaz Dawalibi 2024-09-11 16:47:42 +03:00
commit 553d749633
28 changed files with 276 additions and 222 deletions

View File

@ -8,7 +8,6 @@ import {
} from "@ant-design/icons"; } from "@ant-design/icons";
import React from "react"; import React from "react";
import { Image, Space } from "antd"; import { Image, Space } from "antd";
import { ImageBaseURL } from "../../api/config";
import useImageError from "../../Hooks/useImageError"; import useImageError from "../../Hooks/useImageError";
import { ErrorImage } from "../../Layout/app/Const"; import { ErrorImage } from "../../Layout/app/Const";

View File

@ -13,9 +13,6 @@ const ImageBoxField = ({ name }: any) => {
const value = getNestedValue(formik.values, name); const value = getNestedValue(formik.values, name);
const [imagePreview, setImagePreview] = useState<string | null>(null); const [imagePreview, setImagePreview] = useState<string | null>(null);
const fileInputRef = useRef<HTMLInputElement | null>(null); const fileInputRef = useRef<HTMLInputElement | null>(null);
console.log(formik.values);
console.log(value, name);
useEffect(() => { useEffect(() => {
if (value instanceof File) { if (value instanceof File) {

View File

@ -1,7 +1,6 @@
import { Button, Image, Upload, UploadFile } from "antd"; import { Button, Image, Upload, UploadFile } from "antd";
import useFormField from "../../Hooks/useFormField"; import useFormField from "../../Hooks/useFormField";
import { UploadOutlined } from "@ant-design/icons"; import { UploadOutlined } from "@ant-design/icons";
import { ImageBaseURL } from "../../api/config";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { FaRegFilePdf } from "react-icons/fa"; import { FaRegFilePdf } from "react-icons/fa";
import { useState } from "react"; import { useState } from "react";
@ -17,7 +16,7 @@ const PdfUploader = ({
}: any) => { }: any) => {
const { formik, t, isError } = useFormField(name, props); const { formik, t, isError } = useFormField(name, props);
let FormikName = formik.values[name]; let FormikName = formik.values[name];
const imageUrl = formik.values[name] ? ImageBaseURL + FormikName : ""; const imageUrl = formik.values[name] ? FormikName : "";
const [Imageurl, setImageurl] = useState(null); const [Imageurl, setImageurl] = useState(null);
const FilehandleChange = (value: any) => { const FilehandleChange = (value: any) => {

View File

@ -38,10 +38,19 @@ const SelectTag: React.FC = () => {
const options = data?.data ?? []; const options = data?.data ?? [];
const additionalData = const additionalData =
options?.length < 1 && searchValue.length > 1 && !isLoading options.length < 1 && searchValue.length > 1 && !isLoading
? [{ id: `${searchValue}`, name: searchValue }] ? [{ id: searchValue, name: searchValue }]
: []; : [];
console.log(options);
console.log(formik?.values?.tags);
const value = formik?.values?.tags?.map((item: any) => item?.id ?? item) ?? [];
const AllOptions = [...options, ...additionalData]
console.log(AllOptions);
return ( return (
<div className="SelectTag"> <div className="SelectTag">
<label htmlFor="">{t("models.tag")}</label> <label htmlFor="">{t("models.tag")}</label>
@ -52,7 +61,7 @@ const SelectTag: React.FC = () => {
placeholder="" placeholder=""
fieldNames={{ label: "name", value: "id" }} fieldNames={{ label: "name", value: "id" }}
onChange={handleChange} onChange={handleChange}
options={[...options, ...additionalData]} options={AllOptions}
filterOption={false} filterOption={false}
loading={isLoading} loading={isLoading}
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")} notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
@ -66,7 +75,7 @@ const SelectTag: React.FC = () => {
handleBlur(); handleBlur();
} }
}} }}
value={formik?.values?.tags ?? []} value={value}
/> />
</div> </div>
); );

View File

@ -0,0 +1,30 @@
import React from 'react'
interface IFilterBody {
children:React.ReactNode
}
const useFilter = () => {
const FilterButton = ()=>{
return (
<div>
FilterButton
</div>
)
}
const FilterBody = ({children}:IFilterBody)=>{
return (
<div>
FilterBody
</div>
)
}
return {
FilterButton , FilterBody
}
}
export default useFilter

View File

@ -0,0 +1,5 @@
export enum FilterEnum {
FILTER="FILTER"
}

View File

@ -0,0 +1,22 @@
import { create } from "zustand";
interface FilterState {
filterState: any[];
setFilterState: (data: any) => void;
clearFilterState: () => void;
setWithOldValue: (data: any) => void;
setInitialValue: (data: any) => void;
}
export const useFilterState = create<FilterState>((set, get) => ({
filterState: [],
setFilterState: (data) => set(() => ({ filterState: data })),
clearFilterState: () => set(() => ({ filterState: [] })),
setWithOldValue: (data) =>
set((state) => ({ filterState: [...state.filterState, data] })),
setInitialValue: (data) => {
if (get().filterState.length < 1) {
set(() => ({ filterState: data }));
}
},
}));

View File

@ -0,0 +1,32 @@
import { useEffect } from 'react';
type KeyCombination = {
ctrlKey?: boolean;
shiftKey?: boolean;
code: string; // Use string here for flexibility
};
const useKeyCombination = (keyCombination: KeyCombination, callback: () => void) => {
useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => {
const matches =
(keyCombination.ctrlKey === undefined || event.ctrlKey === keyCombination.ctrlKey) &&
(keyCombination.shiftKey === undefined || event.shiftKey === keyCombination.shiftKey) &&
event.code === keyCombination.code;
if (matches) {
callback();
event.preventDefault(); // Prevent the default action for the event
event.stopPropagation(); // Stop the event from propagating further
}
};
window.addEventListener('keydown', handleKeyDown);
return () => {
window.removeEventListener('keydown', handleKeyDown);
};
}, [keyCombination, callback]);
};
export default useKeyCombination;

View File

@ -21,20 +21,6 @@ import ModelForm from "./Model/ModelForm";
const AcceptModal = lazy(() => import("./Model/AcceptModal")); const AcceptModal = lazy(() => import("./Model/AcceptModal"));
import { useModalState } from "../../../zustand/Modal"; import { useModalState } from "../../../zustand/Modal";
import { ModalEnum } from "../../../enums/Model";
import { cleanObject } from "../../../utils/cleanObject";
import { hasItems } from "../../../utils/hasItems";
import { QUESTION_OBJECT_KEY } from "../../../config/AppKey";
import useSaveOnDisconnect from "../../../Hooks/useSaveOnDisconnect";
import { getLocalStorageQuestions } from "../../../utils/setLocalStorageQuestions";
import { toast } from "react-toastify";
import useSetPageTitle from "../../../Hooks/useSetPageTitle";
import { useGetAllUnit } from "../../../api/unit";
import { useGetAllLesson } from "../../../api/lesson";
import { useGetAllSubject } from "../../../api/subject";
import { useGetAllGrade } from "../../../api/grade";
import { useGetAllCurriculum } from "../../../api/curriculum";
const AddPage: React.FC = () => { const AddPage: React.FC = () => {
const { isSuccess: isSuccessAsync, mutateAsync } = useAddQuestionAsync(); const { isSuccess: isSuccessAsync, mutateAsync } = useAddQuestionAsync();
const { mutate, isSuccess, isLoading } = useAddQuestion(); const { mutate, isSuccess, isLoading } = useAddQuestion();
@ -43,8 +29,6 @@ const AddPage: React.FC = () => {
setTagsSearch, setTagsSearch,
setObjectToEdit, setObjectToEdit,
objectToEdit, objectToEdit,
setSuccess,
SavedQuestionData,
} = useObjectToEdit(); } = useObjectToEdit();
const { setIsOpen } = useModalState((state) => state); const { setIsOpen } = useModalState((state) => state);
@ -52,52 +36,8 @@ const AddPage: React.FC = () => {
const [t] = useTranslation(); const [t] = useTranslation();
const { unit_id, curriculum_id, grade_id, subject_id, lesson_id } = const { unit_id, curriculum_id, grade_id, subject_id, lesson_id } =
useParams<ParamsEnum>(); useParams<ParamsEnum>();
const { data: unit } = useGetAllUnit({ show: unit_id });
const { data: Subject } = useGetAllSubject({
show: subject_id,
});
const { data: grade } = useGetAllGrade({
show: grade_id,
});
const { data: Curriculum } = useGetAllCurriculum({
show: curriculum_id,
});
const { data: Lesson } = useGetAllLesson({
show: lesson_id,
});
const gradeName = grade?.data?.name ?? "";
const SubjectName = Subject?.data?.name ?? "";
const CurriculumName = Curriculum?.data?.name ?? "";
const unitName = unit?.data?.name ?? "";
const LessonName = Lesson?.data?.name ?? "";
useSetPageTitle(
t(`page_header.grade`) +
"/" +
gradeName +
"/" +
t(`PageTitle.subject`) +
"/" +
SubjectName +
"/" +
t("PageTitle.curriculum") +
"/" +
CurriculumName +
"/" +
t("PageTitle.unit") +
"/" +
unitName +
"/" +
t("PageTitle.lesson") +
"/" +
LessonName +
"/" +
t("PageTitle.question") +
"/" +
t("practical.add"),
);
const handleSubmit = ( const handleSubmit = (
values: any, values: any,
@ -206,6 +146,9 @@ const AddPage: React.FC = () => {
// } // }
}; };
if (isBseQuestion) { if (isBseQuestion) {
return ( return (
<div className="exercise_add"> <div className="exercise_add">

View File

@ -14,7 +14,6 @@ import {
useGetAllQuestion, useGetAllQuestion,
useUpdateQuestion, useUpdateQuestion,
} from "../../../api/Question"; } from "../../../api/Question";
import { useQueryClient } from "react-query";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import { ParamsEnum } from "../../../enums/params"; import { ParamsEnum } from "../../../enums/params";
@ -25,18 +24,10 @@ import ModelForm from "./Model/ModelForm";
import BaseForm from "./Model/Malty/Form"; 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 useSetPageTitle from "../../../Hooks/useSetPageTitle";
import { useGetAllUnit } from "../../../api/unit";
import { useGetAllLesson } from "../../../api/lesson";
import { useGetAllSubject } from "../../../api/subject";
import { useGetAllGrade } from "../../../api/grade";
import { useGetAllCurriculum } from "../../../api/curriculum";
const EditPage: React.FC = () => { const EditPage: React.FC = () => {
const { const {
unit_id,
curriculum_id,
grade_id,
subject_id, subject_id,
lesson_id, lesson_id,
question_id, question_id,
@ -54,8 +45,7 @@ const EditPage: React.FC = () => {
const { data: Questions, isLoading: QuestionsDataLoading } = const { data: Questions, isLoading: QuestionsDataLoading } =
useGetAllQuestion({ useGetAllQuestion({
questionParentId: question_id, parent_id: question_id,
onlyWithNoParents: false,
}); });
const objectToEdit = { ...data?.data, Questions: Questions?.data }; const objectToEdit = { ...data?.data, Questions: Questions?.data };
@ -67,52 +57,8 @@ const EditPage: React.FC = () => {
}, [objectToEdit?.isBase]); }, [objectToEdit?.isBase]);
const [t] = useTranslation(); const [t] = useTranslation();
const { data: unit } = useGetAllUnit({ show: unit_id });
const { data: Subject } = useGetAllSubject({
show: subject_id,
});
const { data: grade } = useGetAllGrade({
show: grade_id,
});
const { data: Curriculum } = useGetAllCurriculum({
show: curriculum_id,
});
const { data: Lesson } = useGetAllLesson({
show: lesson_id,
});
const gradeName = grade?.data?.name ?? "";
const SubjectName = Subject?.data?.name ?? "";
const CurriculumName = Curriculum?.data?.name ?? "";
const unitName = unit?.data?.name ?? "";
const LessonName = Lesson?.data?.name ?? "";
useSetPageTitle(
t(`page_header.grade`) +
"/" +
gradeName +
"/" +
t(`PageTitle.subject`) +
"/" +
SubjectName +
"/" +
t("PageTitle.curriculum") +
"/" +
CurriculumName +
"/" +
t("PageTitle.unit") +
"/" +
unitName +
"/" +
t("PageTitle.lesson") +
"/" +
LessonName +
"/" +
t("PageTitle.question") +
"/" +
t("practical.edit"),
);
const handleSubmit = (values: any) => { const handleSubmit = (values: any) => {
const DataToSend = structuredClone(values); const DataToSend = structuredClone(values);
@ -123,13 +69,13 @@ const EditPage: React.FC = () => {
const UpdateBseQuestion = { const UpdateBseQuestion = {
id: DataToSend?.id, id: DataToSend?.id,
content: DataToSend?.content, content: DataToSend?.content,
image: DataToSend?.image ?? "", content_image: DataToSend?.content_image ?? "",
}; };
if ( if (
typeof UpdateBseQuestion?.image === "string" && typeof UpdateBseQuestion?.content_image === "string" &&
UpdateBseQuestion?.image !== "" UpdateBseQuestion?.content_image !== ""
) { ) {
delete UpdateBseQuestion["image"]; delete UpdateBseQuestion["content_image"];
} }
console.log(DeletedQuestions, "DeletedQuestions"); console.log(DeletedQuestions, "DeletedQuestions");
console.log(UpdateBseQuestion); console.log(UpdateBseQuestion);
@ -147,24 +93,24 @@ const EditPage: React.FC = () => {
console.log(item); console.log(item);
if (item?.id) { if (item?.id) {
const itemToSend = structuredClone(item); const itemToSend = structuredClone(item);
const keysToRemove = ["image", "answer_image"]; const keysToRemove = ["content_image"];
const updatedObject = removeStringKeys(itemToSend, keysToRemove); const updatedObject = removeStringKeys(itemToSend, keysToRemove);
console.log(updatedObject, "updatedObject"); console.log(updatedObject, "updatedObject");
const tags = processTags(updatedObject); const tags = processTags(updatedObject);
const oldanswers = [] as any; const oldAnswers = [] as any;
const newanswers = [] as any; const newAnswers = [] as any;
updatedObject?.answers?.forEach((item: any) => { updatedObject?.answers?.forEach((item: any) => {
if (item?.id) { if (item?.id) {
oldanswers.push(item); oldAnswers.push({...item,isCorrect:item?.isCorrect ? 1 : 0});
} else { } else {
newanswers.push(item); newAnswers.push({...item,isCorrect:item?.isCorrect ? 1 : 0});
} }
}); });
const answers = { const answers = {
old: oldanswers, old: oldAnswers,
new: newanswers, new: newAnswers,
}; };
console.log(answers); console.log(answers);
@ -187,34 +133,31 @@ const EditPage: React.FC = () => {
} }
}); });
} else { } else {
const keysToRemove = ["image", "answer_image"];
const keysToRemove = ["content_image"];
console.log(DataToSend);
const updatedObject = removeStringKeys(DataToSend, keysToRemove); const updatedObject = removeStringKeys(DataToSend, keysToRemove);
delete updatedObject["parent_id"]; delete updatedObject["parent_id"];
const tags = processTags(updatedObject); const tags = processTags(updatedObject);
console.log(updatedObject, "updatedObject"); if (!updatedObject?.content_image) {
if (!updatedObject?.image) { updatedObject["content_image"] = "";
updatedObject["image"] = "";
} }
console.log(updatedObject);
const oldanswers = [] as any; const oldAnswers = [] as any;
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); oldAnswers.push({...item,isCorrect:item?.isCorrect ? 1 : 0});
oldanswers.push(item);
} else { } else {
newanswers.push(item); newAnswers.push({...item,isCorrect:item?.isCorrect ? 1 : 0});
} }
}); });
const answers = { const answers = {
old: oldanswers, old: oldAnswers,
new: newanswers, new: newAnswers,
}; };
console.log(answers, "answers");
mutate({ ...updatedObject, answers, tags }); mutate({ ...updatedObject, answers, tags });
} }

View File

@ -28,6 +28,7 @@ const ChoiceFields = ({ index, data }: { index: number; data: Choice }) => {
return ( return (
<> <>
<div className="ChoiceFields"> <div className="ChoiceFields">
<TextField <TextField
className="textarea_exercise" className="textarea_exercise"
placeholder={"choice"} placeholder={"choice"}

View File

@ -3,6 +3,9 @@ import { Choice } from "../../../../../types/Item";
import ChoiceFields from "./ChoiceFields"; import ChoiceFields from "./ChoiceFields";
import { useFormikContext } from "formik"; import { useFormikContext } from "formik";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd"; import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";
import { FaIcons } from "react-icons/fa";
import { DragHandleUnit } from "../../../Unit/DrapableTable";
import { HolderOutlined } from "@ant-design/icons";
const Choices = () => { const Choices = () => {
const formik = useFormikContext<any>(); const formik = useFormikContext<any>();
@ -55,6 +58,9 @@ const Choices = () => {
{...provided.draggableProps} {...provided.draggableProps}
{...provided.dragHandleProps} {...provided.dragHandleProps}
> >
<div className="HolderQuestion">
<HolderOutlined/>
</div>
<ChoiceFields index={index} data={item} /> <ChoiceFields index={index} data={item} />
</div> </div>
)} )}

View File

@ -67,6 +67,10 @@ const Form = () => {
}; };
const [t] = useTranslation(); const [t] = useTranslation();
return ( return (
<Row className="w-100"> <Row className="w-100">
<div className="exercise_form"> <div className="exercise_form">

View File

@ -43,6 +43,8 @@ const ChoiceFields = ({
].answers.filter((_: any, i: any) => i !== index); ].answers.filter((_: any, i: any) => i !== index);
formik.setFieldValue(`Questions[${parent_index}].answers`, updatedAnswers); formik.setFieldValue(`Questions[${parent_index}].answers`, updatedAnswers);
}; };
return ( return (
<> <>
<div className="ChoiceFields"> <div className="ChoiceFields">
@ -60,7 +62,7 @@ const ChoiceFields = ({
/> />
<ImageBoxField <ImageBoxField
name={`Questions.${parent_index}.answers.${index}.answer_image`} name={`Questions.${parent_index}.answers.${index}.content_image`}
/> />
<div className="answer_status"> <div className="answer_status">

View File

@ -3,6 +3,7 @@ import ChoiceFields from "./ChoiceFields";
import { Choice } from "../../../../../../types/Item"; import { Choice } from "../../../../../../types/Item";
import { useFormikContext } from "formik"; import { useFormikContext } from "formik";
import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd"; import { DragDropContext, Draggable, Droppable } from "react-beautiful-dnd";
import { HolderOutlined } from "@ant-design/icons";
const Choices = ({ parent_index }: { parent_index: number }) => { const Choices = ({ parent_index }: { parent_index: number }) => {
const formik = useFormikContext<any>(); const formik = useFormikContext<any>();
@ -67,6 +68,9 @@ const Choices = ({ parent_index }: { parent_index: number }) => {
{...provided.draggableProps} {...provided.draggableProps}
{...provided.dragHandleProps} {...provided.dragHandleProps}
> >
<div className="HolderQuestion">
<HolderOutlined/>
</div>
<ChoiceFields <ChoiceFields
key={index} key={index}
parent_index={parent_index} parent_index={parent_index}

View File

@ -13,6 +13,8 @@ import { useObjectToEdit } from "../../../../../zustand/ObjectToEditState";
import Choices from "./ChoiceField/Choices"; import Choices from "./ChoiceField/Choices";
import ImageBoxField from "../../../../../Components/CustomFields/ImageBoxField/ImageBoxField"; import ImageBoxField from "../../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
import MaltySelectTag from "./Tags/MaltySelectTag"; import MaltySelectTag from "./Tags/MaltySelectTag";
import useKeyCombination from "../../../../../Hooks/useKeyCombination";
import { CombinationKeyEnum } from "../../../../../enums/CombinationKeyEnum";
const Form = () => { const Form = () => {
const formik = useFormikContext<any>(); const formik = useFormikContext<any>();
@ -36,8 +38,7 @@ const Form = () => {
console.log(parent_index); console.log(parent_index);
formik.setFieldValue(`Questions.[${parent_index}].answers`, [ formik.setFieldValue(`Questions.[${parent_index}].answers`, [
...((formik?.values as any)?.Questions?.[parent_index] ...((formik?.values as any)?.Questions?.[parent_index]?.answers as Choice[]),
.answers as Choice[]),
{ {
answer: null, answer: null,
@ -69,7 +70,21 @@ const Form = () => {
}; };
const [t] = useTranslation(); const [t] = useTranslation();
const lastQuestions = formik?.values?.Questions?.length -1 ;
useKeyCombination({ ctrlKey: true, shiftKey: true, code: CombinationKeyEnum.CHOICE }, () => {
handleAddChoice(lastQuestions)
});
useKeyCombination({ ctrlKey: true, shiftKey: true, code: CombinationKeyEnum.QUESTION }, () => {
handleAddQuestion()
});
return ( return (
<Row className="w-100 exercise_form_container"> <Row className="w-100 exercise_form_container">
<div className="exercise_form"> <div className="exercise_form">
<ValidationField <ValidationField
@ -78,7 +93,7 @@ const Form = () => {
label="main_question" label="main_question"
type="TextArea" type="TextArea"
/> />
<ImageBoxField name="image" /> <ImageBoxField name="content_image" />
<div></div> <div></div>
</div> </div>
@ -113,7 +128,7 @@ const Form = () => {
<ValidationField <ValidationField
className=" " className=" "
placeholder="_" placeholder="_"
name={`answers.${parent_index}.hint`} name={`Questions.${parent_index}.hint`}
label="hint_question" label="hint_question"
type="text" type="text"
style={{ width: "100%" }} style={{ width: "100%" }}

View File

@ -51,7 +51,7 @@ const QuestionFIeld = ({ index, data }: { index: number; data: Choice }) => {
type="TextArea" type="TextArea"
/> />
<ImageBoxField name={`Questions.${index}.image`} /> <ImageBoxField name={`Questions.${index}.content_image`} />
<div className="answer_status"> <div className="answer_status">
<p className="delete_question_options"> <p className="delete_question_options">

View File

@ -37,10 +37,19 @@ const MaltySelectTag = ({ parent_index }: { parent_index: number }) => {
const options = data?.data ?? []; const options = data?.data ?? [];
const additionalData = const additionalData =
options?.length < 1 && searchValue.length > 1 && !isLoading options.length < 1 && searchValue.length > 1 && !isLoading
? [{ id: `new_${searchValue}`, name: searchValue }] ? [{ id: searchValue, name: searchValue }]
: []; : [];
console.log(options);
const value = formik?.values?.Questions[parent_index]?.tags?.map((item: any) => item?.id ?? item) ?? [];
console.log(formik?.values?.Questions[parent_index]);
console.log(value);
const AllOptions = [...options, ...additionalData]
return ( return (
<div className="SelectTag"> <div className="SelectTag">
<label htmlFor="">{t("models.tag")}</label> <label htmlFor="">{t("models.tag")}</label>
@ -50,8 +59,9 @@ const MaltySelectTag = ({ parent_index }: { parent_index: number }) => {
style={{ width: "100%", height: "40px" }} style={{ width: "100%", height: "40px" }}
placeholder="" placeholder=""
fieldNames={{ label: "name", value: "id" }} fieldNames={{ label: "name", value: "id" }}
onChange={handleChange} onChange={handleChange}
options={[...options, ...additionalData]} options={AllOptions}
filterOption={false} filterOption={false}
loading={isLoading} loading={isLoading}
notFoundContent={isLoading ? <Spin /> : t("practical.not_found")} notFoundContent={isLoading ? <Spin /> : t("practical.not_found")}
@ -65,7 +75,7 @@ const MaltySelectTag = ({ parent_index }: { parent_index: number }) => {
handleBlur(); handleBlur();
} }
}} }}
value={values ?? []} value={value}
/> />
</div> </div>
); );

View File

@ -11,6 +11,8 @@ import { useEffect } from "react";
import Choices from "./Field/Choices"; import Choices from "./Field/Choices";
import ImageBoxField from "../../../../Components/CustomFields/ImageBoxField/ImageBoxField"; import ImageBoxField from "../../../../Components/CustomFields/ImageBoxField/ImageBoxField";
import SelectTag from "../../../../Components/CustomFields/SelectTag"; import SelectTag from "../../../../Components/CustomFields/SelectTag";
import useKeyCombination from "../../../../Hooks/useKeyCombination";
import { CombinationKeyEnum } from "../../../../enums/CombinationKeyEnum";
const Form = () => { const Form = () => {
const [t] = useTranslation(); const [t] = useTranslation();
@ -42,7 +44,13 @@ const Form = () => {
]); ]);
}; };
console.log(formik?.values);
useKeyCombination({ ctrlKey: true, shiftKey: true, code: CombinationKeyEnum.CHOICE }, () => {
handleAddChoice()
});
return ( return (
<Row className="w-100 exercise_form_container"> <Row className="w-100 exercise_form_container">

View File

@ -5,9 +5,9 @@ import { QUESTION_OBJECT_KEY } from "../../../../config/AppKey";
export const getInitialValues = (objectToEdit: Question): any => { export const getInitialValues = (objectToEdit: Question): any => {
const tags = objectToEdit?.tags?.map((item: any, index: number) => { const tags = objectToEdit?.tags?.map((item: any, index: number) => {
return { ...item, key: index }; return { ...item };
}); });
console.log(objectToEdit); console.log(tags);
return { return {
id: objectToEdit?.id ?? null, id: objectToEdit?.id ?? null,
@ -45,13 +45,14 @@ export const getInitialValuesBase = (objectToEdit: Question): any => {
const tags = item?.tags?.map((tag: any) => ({ const tags = item?.tags?.map((tag: any) => ({
id: tag?.id, id: tag?.id,
name: tag?.name, name: tag?.name,
key: `${tag?.id}_key_${tag?.name}`,
})); }));
console.log(tags);
return { return {
...item, ...item,
canAnswersBeShuffled: objectToEdit?.canAnswersBeShuffled ? 1 : 0, canAnswersBeShuffled: objectToEdit?.canAnswersBeShuffled ? 1 : 0,
hint: item?.hint ?? "", hint: objectToEdit?.hint ?? "",
isBase:0,
tags, tags,
}; };
}); });

View File

@ -24,7 +24,7 @@ const TableHeader = () => {
const deleteMutation = useDeleteQuestion(); const deleteMutation = useDeleteQuestion();
const { unit_id, curriculum_id, grade_id, subject_id, lesson_id } = const { unit_id, grade_id, subject_id, lesson_id } =
useParams<ParamsEnum>(); useParams<ParamsEnum>();
const { data: unit } = useGetAllUnit({ show: unit_id }); const { data: unit } = useGetAllUnit({ show: unit_id });
@ -34,16 +34,13 @@ const TableHeader = () => {
const { data: grade } = useGetAllGrade({ const { data: grade } = useGetAllGrade({
show: grade_id, show: grade_id,
}); });
const { data: Curriculum } = useGetAllCurriculum({
show: curriculum_id,
});
const { data: Lesson } = useGetAllLesson({ const { data: Lesson } = useGetAllLesson({
show: lesson_id, show: lesson_id,
}); });
const gradeName = grade?.data?.name ?? ""; const gradeName = grade?.data?.name ?? "";
const SubjectName = Subject?.data?.name ?? ""; const SubjectName = Subject?.data?.name ?? "";
const CurriculumName = Curriculum?.data?.name ?? "";
const unitName = unit?.data?.name ?? ""; const unitName = unit?.data?.name ?? "";
const LessonName = Lesson?.data?.name ?? ""; const LessonName = Lesson?.data?.name ?? "";
@ -56,10 +53,6 @@ const TableHeader = () => {
"/" + "/" +
SubjectName + SubjectName +
"/" + "/" +
t("PageTitle.curriculum") +
"/" +
CurriculumName +
"/" +
t("PageTitle.unit") + t("PageTitle.unit") +
"/" + "/" +
unitName + unitName +

View File

@ -2,12 +2,21 @@ import React from "react";
import { useTranslation } from "react-i18next"; import { useTranslation } from "react-i18next";
import { ABILITIES_ENUM } from "../../enums/abilities"; import { ABILITIES_ENUM } from "../../enums/abilities";
import useSetPageTitle from "../../Hooks/useSetPageTitle"; import useSetPageTitle from "../../Hooks/useSetPageTitle";
import useFilter from "../../Components/FilterField/components/useFilter";
const Dummy = () => { const Dummy = () => {
const [t] = useTranslation(); const [t] = useTranslation();
useSetPageTitle(`${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t("dashboard")}`); useSetPageTitle(`${t(ABILITIES_ENUM?.MAIN_PAGE)} / ${t("dashboard")}`);
const {FilterButton,FilterBody} = useFilter()
return(
<div className="DummyHomePage">
<FilterButton/>
<FilterBody>
karim
</FilterBody>
return <div className="DummyHomePage"></div>; </div>
);
}; };
export default Dummy; export default Dummy;

View File

@ -205,3 +205,8 @@
padding-inline: 20px !important; padding-inline: 20px !important;
} }
} }
.HolderQuestion{
transform: translateY(25px);
}

View File

@ -1,4 +1,4 @@
export const BaseURL = "https://nerd-back.point-dev.net/api/"; export const BaseURL = "https://nerd-back.point-dev.net/api/";
// export const BaseURL = "http://192.168.1.109:8000/api/";
export const ImageBaseURL = "https://nerd-back.point-dev.net/api/";
export const HEADER_KEY = "X-Custom-Query-Key"; export const HEADER_KEY = "X-Custom-Query-Key";

View File

@ -0,0 +1,6 @@
export enum CombinationKeyEnum {
QUESTION = "KeyK",
CHOICE = "KeyJ"
}

View File

@ -245,7 +245,7 @@
"Pass": "نجاح", "Pass": "نجاح",
"users": "المستخدمين", "users": "المستخدمين",
"branchAdmin": "مسؤول الفروع", "branchAdmin": "مسؤول الفروع",
"grade": "الدرجات", "grade": "الصفوف",
"homeworkAttachment": "مرفق الواجب المنزلي", "homeworkAttachment": "مرفق الواجب المنزلي",
"lateArrival": "وصول متأخر", "lateArrival": "وصول متأخر",
"noteAttachment": "مرفق الملاحظة", "noteAttachment": "مرفق الملاحظة",
@ -692,7 +692,7 @@
"tags": "كلمات مفتاحية", "tags": "كلمات مفتاحية",
"main_menu": "القائمة الرئيسية", "main_menu": "القائمة الرئيسية",
"setting": "الإعدادات", "setting": "الإعدادات",
"grade": "الدرجات", "grade": "الصفوف",
"curriculum": "مقرر", "curriculum": "مقرر",
"package": "حزمة", "package": "حزمة",
"subjects": "مواد", "subjects": "مواد",
@ -762,7 +762,7 @@
"Question": "لوحة القيادة /اسئلة ", "Question": "لوحة القيادة /اسئلة ",
"add_Question": "لوحة القيادة /إضافة اسئلة ", "add_Question": "لوحة القيادة /إضافة اسئلة ",
"edit_Question": "لوحة القيادة /تعديل اسئلة ", "edit_Question": "لوحة القيادة /تعديل اسئلة ",
"grade": "الدرجات", "grade": "الصفوف",
"report": "تقرير", "report": "تقرير",
"user": "مستخدم", "user": "مستخدم",
"reseller":" لوحة القيادة / البائعين", "reseller":" لوحة القيادة / البائعين",
@ -774,31 +774,31 @@
"reseller":"البائعين" "reseller":"البائعين"
}, },
"alphabet": { "alphabet": {
"A": "أ", "A": "A",
"B": "ب", "B": "B",
"C": "ت", "C": "C",
"D": "ث", "D": "D",
"E": "ج", "E": "E",
"F": "ح", "F": "F",
"G": "خ", "G": "G",
"H": "د", "H": "H",
"I": "ذ", "I": "I",
"J": "ر", "J": "J",
"K": "ز", "K": "K",
"L": "س", "L": "L",
"M": "ش", "M": "M",
"N": "ص", "N": "N",
"O": "ض", "O": "O",
"P": "ط", "P": "P",
"Q": "ظ", "Q": "Q",
"R": "ع", "R": "R",
"S": "غ", "S": "S",
"T": "ف", "T": "T",
"U": "ق", "U": "U",
"V": "ك", "V": "V",
"W": "ل", "W": "W",
"X": "م", "X": "X",
"Y": "ن", "Y": "Y",
"Z": "ه" "Z": "Z"
} }
} }

View File

@ -1,11 +1,23 @@
export function removeStringKeys(obj: any, keysToRemove: string[]): any { export function removeStringKeys(obj: any, keysToRemove: string[]): any {
if (typeof obj === "object" && obj !== null) { // Check if the input is an object or array
if (obj && typeof obj === 'object') {
// Handle arrays
if (Array.isArray(obj)) {
obj.forEach((item, index) => {
obj[index] = removeStringKeys(item, keysToRemove);
});
} else {
// Handle objects
for (const key in obj) { for (const key in obj) {
if (obj.hasOwnProperty(key)) { if (obj.hasOwnProperty(key)) {
if (keysToRemove.includes(key) && typeof obj[key] === "string") { const value = obj[key];
// Check if the value is a string or "null" and the key is in keysToRemove
if (keysToRemove.includes(key) && (typeof value === 'string' || value === 'null')) {
delete obj[key]; delete obj[key];
} else { } else {
removeStringKeys(obj[key], keysToRemove); // Recursively process nested objects or arrays
obj[key] = removeStringKeys(value, keysToRemove);
}
} }
} }
} }

View File

@ -15,7 +15,6 @@ const useAuthState = create<AuthStore>((set) => {
const storedToken = localStorage.getItem(TOKEN_KEY); const storedToken = localStorage.getItem(TOKEN_KEY);
const storedAbilities = localStorage.getItem(ABILITIES_KEY); const storedAbilities = localStorage.getItem(ABILITIES_KEY);
const storedType = localStorage.getItem(TYPE_KEY); const storedType = localStorage.getItem(TYPE_KEY);
console.log(storedAbilities);
return { return {
isAuthenticated: !!storedToken, isAuthenticated: !!storedToken,